Whamcloud - gitweb
LU-11848 lov: FIEMAP support for PFL and FLR file
[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-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
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 nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
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_24G () {
1454         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1455
1456         local ino1
1457         local ino2
1458
1459         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1460         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1461         touch $DIR/$tdir-0/f1 || error "touch f1"
1462         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1463         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1464         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1465         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1466         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1467 }
1468 run_test 24G "migrate symlink in rename"
1469
1470 test_25a() {
1471         echo '== symlink sanity ============================================='
1472
1473         test_mkdir $DIR/d25
1474         ln -s d25 $DIR/s25
1475         touch $DIR/s25/foo ||
1476                 error "File creation in symlinked directory failed"
1477 }
1478 run_test 25a "create file in symlinked directory ==============="
1479
1480 test_25b() {
1481         [ ! -d $DIR/d25 ] && test_25a
1482         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1483 }
1484 run_test 25b "lookup file in symlinked directory ==============="
1485
1486 test_26a() {
1487         test_mkdir $DIR/d26
1488         test_mkdir $DIR/d26/d26-2
1489         ln -s d26/d26-2 $DIR/s26
1490         touch $DIR/s26/foo || error "File creation failed"
1491 }
1492 run_test 26a "multiple component symlink ======================="
1493
1494 test_26b() {
1495         test_mkdir -p $DIR/$tdir/d26-2
1496         ln -s $tdir/d26-2/foo $DIR/s26-2
1497         touch $DIR/s26-2 || error "File creation failed"
1498 }
1499 run_test 26b "multiple component symlink at end of lookup ======"
1500
1501 test_26c() {
1502         test_mkdir $DIR/d26.2
1503         touch $DIR/d26.2/foo
1504         ln -s d26.2 $DIR/s26.2-1
1505         ln -s s26.2-1 $DIR/s26.2-2
1506         ln -s s26.2-2 $DIR/s26.2-3
1507         chmod 0666 $DIR/s26.2-3/foo
1508 }
1509 run_test 26c "chain of symlinks"
1510
1511 # recursive symlinks (bug 439)
1512 test_26d() {
1513         ln -s d26-3/foo $DIR/d26-3
1514 }
1515 run_test 26d "create multiple component recursive symlink"
1516
1517 test_26e() {
1518         [ ! -h $DIR/d26-3 ] && test_26d
1519         rm $DIR/d26-3
1520 }
1521 run_test 26e "unlink multiple component recursive symlink"
1522
1523 # recursive symlinks (bug 7022)
1524 test_26f() {
1525         test_mkdir $DIR/$tdir
1526         test_mkdir $DIR/$tdir/$tfile
1527         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1528         test_mkdir -p lndir/bar1
1529         test_mkdir $DIR/$tdir/$tfile/$tfile
1530         cd $tfile                || error "cd $tfile failed"
1531         ln -s .. dotdot          || error "ln dotdot failed"
1532         ln -s dotdot/lndir lndir || error "ln lndir failed"
1533         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1534         output=`ls $tfile/$tfile/lndir/bar1`
1535         [ "$output" = bar1 ] && error "unexpected output"
1536         rm -r $tfile             || error "rm $tfile failed"
1537         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1538 }
1539 run_test 26f "rm -r of a directory which has recursive symlink"
1540
1541 test_27a() {
1542         test_mkdir $DIR/$tdir
1543         $LFS getstripe $DIR/$tdir
1544         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1545         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1546         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1547 }
1548 run_test 27a "one stripe file"
1549
1550 test_27b() {
1551         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1552
1553         test_mkdir $DIR/$tdir
1554         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1555         $LFS getstripe -c $DIR/$tdir/$tfile
1556         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1557                 error "two-stripe file doesn't have two stripes"
1558
1559         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1560 }
1561 run_test 27b "create and write to two stripe file"
1562
1563 # 27c family tests specific striping, setstripe -o
1564 test_27ca() {
1565         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1566         test_mkdir -p $DIR/$tdir
1567         local osts="1"
1568
1569         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1570         $LFS getstripe -i $DIR/$tdir/$tfile
1571         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1572                 error "stripe not on specified OST"
1573
1574         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1575 }
1576 run_test 27ca "one stripe on specified OST"
1577
1578 test_27cb() {
1579         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1580         test_mkdir -p $DIR/$tdir
1581         local osts="1,0"
1582         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1583         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1584         echo "$getstripe"
1585
1586         # Strip getstripe output to a space separated list of OSTs
1587         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1588                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1589         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1590                 error "stripes not on specified OSTs"
1591
1592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1593 }
1594 run_test 27cb "two stripes on specified OSTs"
1595
1596 test_27cc() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1599                 skip "server does not support overstriping"
1600
1601         test_mkdir -p $DIR/$tdir
1602         local osts="0,0"
1603         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1604         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1605         echo "$getstripe"
1606
1607         # Strip getstripe output to a space separated list of OSTs
1608         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1609                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1610         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1611                 error "stripes not on specified OSTs"
1612
1613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1614 }
1615 run_test 27cc "two stripes on the same OST"
1616
1617 test_27cd() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1620                 skip "server does not support overstriping"
1621         test_mkdir -p $DIR/$tdir
1622         local osts="0,1,1,0"
1623         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1624         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1625         echo "$getstripe"
1626
1627         # Strip getstripe output to a space separated list of OSTs
1628         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1629                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1630         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1631                 error "stripes not on specified OSTs"
1632
1633         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1634 }
1635 run_test 27cd "four stripes on two OSTs"
1636
1637 test_27ce() {
1638         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1639                 skip_env "too many osts, skipping"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642         # We do one more stripe than we have OSTs
1643         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1644                 skip_env "ea_inode feature disabled"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts=""
1648         for i in $(seq 0 $OSTCOUNT);
1649         do
1650                 osts=$osts"0"
1651                 if [ $i -ne $OSTCOUNT ]; then
1652                         osts=$osts","
1653                 fi
1654         done
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27ce "more stripes than OSTs with -o"
1668
1669 test_27cf() {
1670         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1671         local pid=0
1672
1673         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1674         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1675         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1676         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1677                 error "failed to set $osp_proc=0"
1678
1679         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1680         pid=$!
1681         sleep 1
1682         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1683         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1684                 error "failed to set $osp_proc=1"
1685         wait $pid
1686         [[ $pid -ne 0 ]] ||
1687                 error "should return error due to $osp_proc=0"
1688 }
1689 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1690
1691 test_27d() {
1692         test_mkdir $DIR/$tdir
1693         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1694                 error "setstripe failed"
1695         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1696         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1697 }
1698 run_test 27d "create file with default settings"
1699
1700 test_27e() {
1701         # LU-5839 adds check for existed layout before setting it
1702         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1703                 skip "Need MDS version at least 2.7.56"
1704
1705         test_mkdir $DIR/$tdir
1706         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1708         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1709 }
1710 run_test 27e "setstripe existing file (should return error)"
1711
1712 test_27f() {
1713         test_mkdir $DIR/$tdir
1714         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1715                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1716         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1717                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1720 }
1721 run_test 27f "setstripe with bad stripe size (should return error)"
1722
1723 test_27g() {
1724         test_mkdir $DIR/$tdir
1725         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1726         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1727                 error "$DIR/$tdir/$tfile has object"
1728 }
1729 run_test 27g "$LFS getstripe with no objects"
1730
1731 test_27ga() {
1732         test_mkdir $DIR/$tdir
1733         touch $DIR/$tdir/$tfile || error "touch failed"
1734         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1735         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1736         local rc=$?
1737         (( rc == 2 )) || error "getstripe did not return ENOENT"
1738 }
1739 run_test 27ga "$LFS getstripe with missing file (should return error)"
1740
1741 test_27i() {
1742         test_mkdir $DIR/$tdir
1743         touch $DIR/$tdir/$tfile || error "touch failed"
1744         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1745                 error "missing objects"
1746 }
1747 run_test 27i "$LFS getstripe with some objects"
1748
1749 test_27j() {
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1752                 error "setstripe failed" || true
1753 }
1754 run_test 27j "setstripe with bad stripe offset (should return error)"
1755
1756 test_27k() { # bug 2844
1757         test_mkdir $DIR/$tdir
1758         local file=$DIR/$tdir/$tfile
1759         local ll_max_blksize=$((4 * 1024 * 1024))
1760         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1761         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1762         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1763         dd if=/dev/zero of=$file bs=4k count=1
1764         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1765         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1766 }
1767 run_test 27k "limit i_blksize for broken user apps"
1768
1769 test_27l() {
1770         mcreate $DIR/$tfile || error "creating file"
1771         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1772                 error "setstripe should have failed" || true
1773 }
1774 run_test 27l "check setstripe permissions (should return error)"
1775
1776 test_27m() {
1777         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1778
1779         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1780                 skip_env "multiple clients -- skipping"
1781
1782         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1783                    head -n1)
1784         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1785                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1786         fi
1787         trap simple_cleanup_common EXIT
1788         test_mkdir $DIR/$tdir
1789         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1790         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1791                 error "dd should fill OST0"
1792         i=2
1793         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1794                 i=$((i + 1))
1795                 [ $i -gt 256 ] && break
1796         done
1797         i=$((i + 1))
1798         touch $DIR/$tdir/$tfile.$i
1799         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1800             awk '{print $1}'| grep -w "0") ] &&
1801                 error "OST0 was full but new created file still use it"
1802         i=$((i + 1))
1803         touch $DIR/$tdir/$tfile.$i
1804         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1805             awk '{print $1}'| grep -w "0") ] &&
1806                 error "OST0 was full but new created file still use it"
1807         simple_cleanup_common
1808 }
1809 run_test 27m "create file while OST0 was full"
1810
1811 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1812 # if the OST isn't full anymore.
1813 reset_enospc() {
1814         local ostidx=${1:-""}
1815         local delay
1816         local ready
1817         local get_prealloc
1818
1819         local list=$(comma_list $(osts_nodes))
1820         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1821
1822         do_nodes $list lctl set_param fail_loc=0
1823         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1824         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1825                 awk '{print $1 * 2;exit;}')
1826         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1827                         grep -v \"^0$\""
1828         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1829 }
1830
1831 __exhaust_precreations() {
1832         local OSTIDX=$1
1833         local FAILLOC=$2
1834         local FAILIDX=${3:-$OSTIDX}
1835         local ofacet=ost$((OSTIDX + 1))
1836
1837         test_mkdir -p -c1 $DIR/$tdir
1838         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1839         local mfacet=mds$((mdtidx + 1))
1840         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1841
1842         local OST=$(ostname_from_index $OSTIDX)
1843
1844         # on the mdt's osc
1845         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1846         local last_id=$(do_facet $mfacet lctl get_param -n \
1847                         osp.$mdtosc_proc1.prealloc_last_id)
1848         local next_id=$(do_facet $mfacet lctl get_param -n \
1849                         osp.$mdtosc_proc1.prealloc_next_id)
1850
1851         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1852         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1853
1854         test_mkdir -p $DIR/$tdir/${OST}
1855         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1856 #define OBD_FAIL_OST_ENOSPC              0x215
1857         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1858         echo "Creating to objid $last_id on ost $OST..."
1859         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1860         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1861         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1862 }
1863
1864 exhaust_precreations() {
1865         __exhaust_precreations $1 $2 $3
1866         sleep_maxage
1867 }
1868
1869 exhaust_all_precreations() {
1870         local i
1871         for (( i=0; i < OSTCOUNT; i++ )) ; do
1872                 __exhaust_precreations $i $1 -1
1873         done
1874         sleep_maxage
1875 }
1876
1877 test_27n() {
1878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1880         remote_mds_nodsh && skip "remote MDS with nodsh"
1881         remote_ost_nodsh && skip "remote OST with nodsh"
1882
1883         reset_enospc
1884         rm -f $DIR/$tdir/$tfile
1885         exhaust_precreations 0 0x80000215
1886         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1887         touch $DIR/$tdir/$tfile || error "touch failed"
1888         $LFS getstripe $DIR/$tdir/$tfile
1889         reset_enospc
1890 }
1891 run_test 27n "create file with some full OSTs"
1892
1893 test_27o() {
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         exhaust_all_precreations 0x215
1902
1903         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1904
1905         reset_enospc
1906         rm -rf $DIR/$tdir/*
1907 }
1908 run_test 27o "create file with all full OSTs (should error)"
1909
1910 test_27p() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         test_mkdir $DIR/$tdir
1919
1920         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1921         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_precreations 0 0x80000215
1925         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1926         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1927         $LFS getstripe $DIR/$tdir/$tfile
1928
1929         reset_enospc
1930 }
1931 run_test 27p "append to a truncated file with some full OSTs"
1932
1933 test_27q() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941
1942         test_mkdir $DIR/$tdir
1943         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1944         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1945                 error "truncate $DIR/$tdir/$tfile failed"
1946         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1947
1948         exhaust_all_precreations 0x215
1949
1950         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1951         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1952
1953         reset_enospc
1954 }
1955 run_test 27q "append to truncated file with all OSTs full (should error)"
1956
1957 test_27r() {
1958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1960         remote_mds_nodsh && skip "remote MDS with nodsh"
1961         remote_ost_nodsh && skip "remote OST with nodsh"
1962
1963         reset_enospc
1964         rm -f $DIR/$tdir/$tfile
1965         exhaust_precreations 0 0x80000215
1966
1967         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1968
1969         reset_enospc
1970 }
1971 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1972
1973 test_27s() { # bug 10725
1974         test_mkdir $DIR/$tdir
1975         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1976         local stripe_count=0
1977         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1978         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1979                 error "stripe width >= 2^32 succeeded" || true
1980
1981 }
1982 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1983
1984 test_27t() { # bug 10864
1985         WDIR=$(pwd)
1986         WLFS=$(which lfs)
1987         cd $DIR
1988         touch $tfile
1989         $WLFS getstripe $tfile
1990         cd $WDIR
1991 }
1992 run_test 27t "check that utils parse path correctly"
1993
1994 test_27u() { # bug 4900
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         remote_mds_nodsh && skip "remote MDS with nodsh"
1997
1998         local index
1999         local list=$(comma_list $(mdts_nodes))
2000
2001 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2002         do_nodes $list $LCTL set_param fail_loc=0x139
2003         test_mkdir -p $DIR/$tdir
2004         trap simple_cleanup_common EXIT
2005         createmany -o $DIR/$tdir/t- 1000
2006         do_nodes $list $LCTL set_param fail_loc=0
2007
2008         TLOG=$TMP/$tfile.getstripe
2009         $LFS getstripe $DIR/$tdir > $TLOG
2010         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2011         unlinkmany $DIR/$tdir/t- 1000
2012         trap 0
2013         [[ $OBJS -gt 0 ]] &&
2014                 error "$OBJS objects created on OST-0. See $TLOG" ||
2015                 rm -f $TLOG
2016 }
2017 run_test 27u "skip object creation on OSC w/o objects"
2018
2019 test_27v() { # bug 4900
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024
2025         exhaust_all_precreations 0x215
2026         reset_enospc
2027
2028         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2029
2030         touch $DIR/$tdir/$tfile
2031         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2032         # all except ost1
2033         for (( i=1; i < OSTCOUNT; i++ )); do
2034                 do_facet ost$i lctl set_param fail_loc=0x705
2035         done
2036         local START=`date +%s`
2037         createmany -o $DIR/$tdir/$tfile 32
2038
2039         local FINISH=`date +%s`
2040         local TIMEOUT=`lctl get_param -n timeout`
2041         local PROCESS=$((FINISH - START))
2042         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2043                error "$FINISH - $START >= $TIMEOUT / 2"
2044         sleep $((TIMEOUT / 2 - PROCESS))
2045         reset_enospc
2046 }
2047 run_test 27v "skip object creation on slow OST"
2048
2049 test_27w() { # bug 10997
2050         test_mkdir $DIR/$tdir
2051         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2052         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2053                 error "stripe size $size != 65536" || true
2054         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2055                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2056 }
2057 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2058
2059 test_27wa() {
2060         [[ $OSTCOUNT -lt 2 ]] &&
2061                 skip_env "skipping multiple stripe count/offset test"
2062
2063         test_mkdir $DIR/$tdir
2064         for i in $(seq 1 $OSTCOUNT); do
2065                 offset=$((i - 1))
2066                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2067                         error "setstripe -c $i -i $offset failed"
2068                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2069                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2070                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2071                 [ $index -ne $offset ] &&
2072                         error "stripe offset $index != $offset" || true
2073         done
2074 }
2075 run_test 27wa "check $LFS setstripe -c -i options"
2076
2077 test_27x() {
2078         remote_ost_nodsh && skip "remote OST with nodsh"
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         OFFSET=$(($OSTCOUNT - 1))
2083         OSTIDX=0
2084         local OST=$(ostname_from_index $OSTIDX)
2085
2086         test_mkdir $DIR/$tdir
2087         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2088         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2089         sleep_maxage
2090         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2091         for i in $(seq 0 $OFFSET); do
2092                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2093                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2094                 error "OST0 was degraded but new created file still use it"
2095         done
2096         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2097 }
2098 run_test 27x "create files while OST0 is degraded"
2099
2100 test_27y() {
2101         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2102         remote_mds_nodsh && skip "remote MDS with nodsh"
2103         remote_ost_nodsh && skip "remote OST with nodsh"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2107         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2108                 osp.$mdtosc.prealloc_last_id)
2109         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2110                 osp.$mdtosc.prealloc_next_id)
2111         local fcount=$((last_id - next_id))
2112         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2113         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2114
2115         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2116                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2117         local OST_DEACTIVE_IDX=-1
2118         local OSC
2119         local OSTIDX
2120         local OST
2121
2122         for OSC in $MDS_OSCS; do
2123                 OST=$(osc_to_ost $OSC)
2124                 OSTIDX=$(index_from_ostuuid $OST)
2125                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2126                         OST_DEACTIVE_IDX=$OSTIDX
2127                 fi
2128                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2129                         echo $OSC "is Deactivated:"
2130                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2131                 fi
2132         done
2133
2134         OSTIDX=$(index_from_ostuuid $OST)
2135         test_mkdir $DIR/$tdir
2136         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2137
2138         for OSC in $MDS_OSCS; do
2139                 OST=$(osc_to_ost $OSC)
2140                 OSTIDX=$(index_from_ostuuid $OST)
2141                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2142                         echo $OST "is degraded:"
2143                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2144                                                 obdfilter.$OST.degraded=1
2145                 fi
2146         done
2147
2148         sleep_maxage
2149         createmany -o $DIR/$tdir/$tfile $fcount
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2155                         echo $OST "is recovered from degraded:"
2156                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2157                                                 obdfilter.$OST.degraded=0
2158                 else
2159                         do_facet $SINGLEMDS lctl --device %$OSC activate
2160                 fi
2161         done
2162
2163         # all osp devices get activated, hence -1 stripe count restored
2164         local stripe_count=0
2165
2166         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2167         # devices get activated.
2168         sleep_maxage
2169         $LFS setstripe -c -1 $DIR/$tfile
2170         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2171         rm -f $DIR/$tfile
2172         [ $stripe_count -ne $OSTCOUNT ] &&
2173                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2174         return 0
2175 }
2176 run_test 27y "create files while OST0 is degraded and the rest inactive"
2177
2178 check_seq_oid()
2179 {
2180         log "check file $1"
2181
2182         lmm_count=$($LFS getstripe -c $1)
2183         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2184         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2185
2186         local old_ifs="$IFS"
2187         IFS=$'[:]'
2188         fid=($($LFS path2fid $1))
2189         IFS="$old_ifs"
2190
2191         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2192         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2193
2194         # compare lmm_seq and lu_fid->f_seq
2195         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2196         # compare lmm_object_id and lu_fid->oid
2197         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2198
2199         # check the trusted.fid attribute of the OST objects of the file
2200         local have_obdidx=false
2201         local stripe_nr=0
2202         $LFS getstripe $1 | while read obdidx oid hex seq; do
2203                 # skip lines up to and including "obdidx"
2204                 [ -z "$obdidx" ] && break
2205                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2206                 $have_obdidx || continue
2207
2208                 local ost=$((obdidx + 1))
2209                 local dev=$(ostdevname $ost)
2210                 local oid_hex
2211
2212                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2213
2214                 seq=$(echo $seq | sed -e "s/^0x//g")
2215                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2216                         oid_hex=$(echo $oid)
2217                 else
2218                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2219                 fi
2220                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2221
2222                 local ff=""
2223                 #
2224                 # Don't unmount/remount the OSTs if we don't need to do that.
2225                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2226                 # update too, until that use mount/ll_decode_filter_fid/mount.
2227                 # Re-enable when debugfs will understand new filter_fid.
2228                 #
2229                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2230                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2231                                 $dev 2>/dev/null" | grep "parent=")
2232                 fi
2233                 if [ -z "$ff" ]; then
2234                         stop ost$ost
2235                         mount_fstype ost$ost
2236                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2237                                 $(facet_mntpt ost$ost)/$obj_file)
2238                         unmount_fstype ost$ost
2239                         start ost$ost $dev $OST_MOUNT_OPTS
2240                         clients_up
2241                 fi
2242
2243                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2244
2245                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2246
2247                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2248                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2249                 #
2250                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2251                 #       stripe_size=1048576 component_id=1 component_start=0 \
2252                 #       component_end=33554432
2253                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2254                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2255                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2256                 local ff_pstripe
2257                 if grep -q 'stripe=' <<<$ff; then
2258                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2259                 else
2260                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2261                         # into f_ver in this case.  See comment on ff_parent.
2262                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2263                 fi
2264
2265                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2266                 [ $ff_pseq = $lmm_seq ] ||
2267                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2268                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2269                 [ $ff_poid = $lmm_oid ] ||
2270                         error "FF parent OID $ff_poid != $lmm_oid"
2271                 (($ff_pstripe == $stripe_nr)) ||
2272                         error "FF stripe $ff_pstripe != $stripe_nr"
2273
2274                 stripe_nr=$((stripe_nr + 1))
2275                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2276                         continue
2277                 if grep -q 'stripe_count=' <<<$ff; then
2278                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2279                                             -e 's/ .*//' <<<$ff)
2280                         [ $lmm_count = $ff_scnt ] ||
2281                                 error "FF stripe count $lmm_count != $ff_scnt"
2282                 fi
2283         done
2284 }
2285
2286 test_27z() {
2287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2288         remote_ost_nodsh && skip "remote OST with nodsh"
2289
2290         test_mkdir $DIR/$tdir
2291         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2292                 { error "setstripe -c -1 failed"; return 1; }
2293         # We need to send a write to every object to get parent FID info set.
2294         # This _should_ also work for setattr, but does not currently.
2295         # touch $DIR/$tdir/$tfile-1 ||
2296         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2297                 { error "dd $tfile-1 failed"; return 2; }
2298         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2299                 { error "setstripe -c -1 failed"; return 3; }
2300         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2301                 { error "dd $tfile-2 failed"; return 4; }
2302
2303         # make sure write RPCs have been sent to OSTs
2304         sync; sleep 5; sync
2305
2306         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2307         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2308 }
2309 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2310
2311 test_27A() { # b=19102
2312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2313
2314         save_layout_restore_at_exit $MOUNT
2315         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2316         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2317                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2318         local default_size=$($LFS getstripe -S $MOUNT)
2319         local default_offset=$($LFS getstripe -i $MOUNT)
2320         local dsize=$(do_facet $SINGLEMDS \
2321                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2322         [ $default_size -eq $dsize ] ||
2323                 error "stripe size $default_size != $dsize"
2324         [ $default_offset -eq -1 ] ||
2325                 error "stripe offset $default_offset != -1"
2326 }
2327 run_test 27A "check filesystem-wide default LOV EA values"
2328
2329 test_27B() { # LU-2523
2330         test_mkdir $DIR/$tdir
2331         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2332         touch $DIR/$tdir/f0
2333         # open f1 with O_LOV_DELAY_CREATE
2334         # rename f0 onto f1
2335         # call setstripe ioctl on open file descriptor for f1
2336         # close
2337         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2338                 $DIR/$tdir/f0
2339
2340         rm -f $DIR/$tdir/f1
2341         # open f1 with O_LOV_DELAY_CREATE
2342         # unlink f1
2343         # call setstripe ioctl on open file descriptor for f1
2344         # close
2345         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2346
2347         # Allow multiop to fail in imitation of NFS's busted semantics.
2348         true
2349 }
2350 run_test 27B "call setstripe on open unlinked file/rename victim"
2351
2352 # 27C family tests full striping and overstriping
2353 test_27Ca() { #LU-2871
2354         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2355
2356         declare -a ost_idx
2357         local index
2358         local found
2359         local i
2360         local j
2361
2362         test_mkdir $DIR/$tdir
2363         cd $DIR/$tdir
2364         for i in $(seq 0 $((OSTCOUNT - 1))); do
2365                 # set stripe across all OSTs starting from OST$i
2366                 $LFS setstripe -i $i -c -1 $tfile$i
2367                 # get striping information
2368                 ost_idx=($($LFS getstripe $tfile$i |
2369                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2370                 echo ${ost_idx[@]}
2371
2372                 # check the layout
2373                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2374                         error "${#ost_idx[@]} != $OSTCOUNT"
2375
2376                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2377                         found=0
2378                         for j in $(echo ${ost_idx[@]}); do
2379                                 if [ $index -eq $j ]; then
2380                                         found=1
2381                                         break
2382                                 fi
2383                         done
2384                         [ $found = 1 ] ||
2385                                 error "Can not find $index in ${ost_idx[@]}"
2386                 done
2387         done
2388 }
2389 run_test 27Ca "check full striping across all OSTs"
2390
2391 test_27Cb() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2395                 skip_env "too many osts, skipping"
2396
2397         test_mkdir -p $DIR/$tdir
2398         local setcount=$(($OSTCOUNT * 2))
2399         [ $setcount -ge 160 ] || large_xattr_enabled ||
2400                 skip_env "ea_inode feature disabled"
2401
2402         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2403                 error "setstripe failed"
2404
2405         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2406         [ $count -eq $setcount ] ||
2407                 error "stripe count $count, should be $setcount"
2408
2409         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2410                 error "overstriped should be set in pattern"
2411
2412         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2413                 error "dd failed"
2414 }
2415 run_test 27Cb "more stripes than OSTs with -C"
2416
2417 test_27Cc() {
2418         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2419                 skip "server does not support overstriping"
2420         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2421
2422         test_mkdir -p $DIR/$tdir
2423         local setcount=$(($OSTCOUNT - 1))
2424
2425         [ $setcount -ge 160 ] || large_xattr_enabled ||
2426                 skip_env "ea_inode feature disabled"
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2436                 error "overstriped should not be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440 }
2441 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2442
2443 test_27Cd() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2447         large_xattr_enabled || skip_env "ea_inode feature disabled"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$LOV_MAX_STRIPE_COUNT
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2460                 error "overstriped should be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464
2465         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2466 }
2467 run_test 27Cd "test maximum stripe count"
2468
2469 test_27Ce() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         test_mkdir -p $DIR/$tdir
2473
2474         pool_add $TESTNAME || error "Pool creation failed"
2475         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2476
2477         local setcount=8
2478
2479         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2480                 error "setstripe failed"
2481
2482         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2483         [ $count -eq $setcount ] ||
2484                 error "stripe count $count, should be $setcount"
2485
2486         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2487                 error "overstriped should be set in pattern"
2488
2489         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2490                 error "dd failed"
2491
2492         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2493 }
2494 run_test 27Ce "test pool with overstriping"
2495
2496 test_27Cf() {
2497         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2498                 skip "server does not support overstriping"
2499         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2500                 skip_env "too many osts, skipping"
2501
2502         test_mkdir -p $DIR/$tdir
2503
2504         local setcount=$(($OSTCOUNT * 2))
2505         [ $setcount -ge 160 ] || large_xattr_enabled ||
2506                 skip_env "ea_inode feature disabled"
2507
2508         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2509                 error "setstripe failed"
2510
2511         echo 1 > $DIR/$tdir/$tfile
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2518                 error "overstriped should be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522
2523         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2524 }
2525 run_test 27Cf "test default inheritance with overstriping"
2526
2527 test_27D() {
2528         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2529         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2530         remote_mds_nodsh && skip "remote MDS with nodsh"
2531
2532         local POOL=${POOL:-testpool}
2533         local first_ost=0
2534         local last_ost=$(($OSTCOUNT - 1))
2535         local ost_step=1
2536         local ost_list=$(seq $first_ost $ost_step $last_ost)
2537         local ost_range="$first_ost $last_ost $ost_step"
2538
2539         test_mkdir $DIR/$tdir
2540         pool_add $POOL || error "pool_add failed"
2541         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2542
2543         local skip27D
2544         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2545                 skip27D+="-s 29"
2546         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2547                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2548                         skip27D+=" -s 30,31"
2549         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2550           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2551                 skip27D+=" -s 32,33"
2552         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2553                 skip27D+=" -s 34"
2554         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2555                 error "llapi_layout_test failed"
2556
2557         destroy_test_pools || error "destroy test pools failed"
2558 }
2559 run_test 27D "validate llapi_layout API"
2560
2561 # Verify that default_easize is increased from its initial value after
2562 # accessing a widely striped file.
2563 test_27E() {
2564         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2565         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2566                 skip "client does not have LU-3338 fix"
2567
2568         # 72 bytes is the minimum space required to store striping
2569         # information for a file striped across one OST:
2570         # (sizeof(struct lov_user_md_v3) +
2571         #  sizeof(struct lov_user_ost_data_v1))
2572         local min_easize=72
2573         $LCTL set_param -n llite.*.default_easize $min_easize ||
2574                 error "lctl set_param failed"
2575         local easize=$($LCTL get_param -n llite.*.default_easize)
2576
2577         [ $easize -eq $min_easize ] ||
2578                 error "failed to set default_easize"
2579
2580         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2581                 error "setstripe failed"
2582         # In order to ensure stat() call actually talks to MDS we need to
2583         # do something drastic to this file to shake off all lock, e.g.
2584         # rename it (kills lookup lock forcing cache cleaning)
2585         mv $DIR/$tfile $DIR/${tfile}-1
2586         ls -l $DIR/${tfile}-1
2587         rm $DIR/${tfile}-1
2588
2589         easize=$($LCTL get_param -n llite.*.default_easize)
2590
2591         [ $easize -gt $min_easize ] ||
2592                 error "default_easize not updated"
2593 }
2594 run_test 27E "check that default extended attribute size properly increases"
2595
2596 test_27F() { # LU-5346/LU-7975
2597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2598         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2599         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2600                 skip "Need MDS version at least 2.8.51"
2601         remote_ost_nodsh && skip "remote OST with nodsh"
2602
2603         test_mkdir $DIR/$tdir
2604         rm -f $DIR/$tdir/f0
2605         $LFS setstripe -c 2 $DIR/$tdir
2606
2607         # stop all OSTs to reproduce situation for LU-7975 ticket
2608         for num in $(seq $OSTCOUNT); do
2609                 stop ost$num
2610         done
2611
2612         # open/create f0 with O_LOV_DELAY_CREATE
2613         # truncate f0 to a non-0 size
2614         # close
2615         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2616
2617         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2618         # open/write it again to force delayed layout creation
2619         cat /etc/hosts > $DIR/$tdir/f0 &
2620         catpid=$!
2621
2622         # restart OSTs
2623         for num in $(seq $OSTCOUNT); do
2624                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2625                         error "ost$num failed to start"
2626         done
2627
2628         wait $catpid || error "cat failed"
2629
2630         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2631         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2632                 error "wrong stripecount"
2633
2634 }
2635 run_test 27F "Client resend delayed layout creation with non-zero size"
2636
2637 test_27G() { #LU-10629
2638         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2639                 skip "Need MDS version at least 2.11.51"
2640         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2641         remote_mds_nodsh && skip "remote MDS with nodsh"
2642         local POOL=${POOL:-testpool}
2643         local ostrange="0 0 1"
2644
2645         test_mkdir $DIR/$tdir
2646         touch $DIR/$tdir/$tfile.nopool
2647         pool_add $POOL || error "pool_add failed"
2648         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2649         $LFS setstripe -p $POOL $DIR/$tdir
2650
2651         local pool=$($LFS getstripe -p $DIR/$tdir)
2652
2653         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2654         touch $DIR/$tdir/$tfile.default
2655         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2656         $LFS find $DIR/$tdir -type f --pool $POOL
2657         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2658         [[ "$found" == "2" ]] ||
2659                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2660
2661         $LFS setstripe -d $DIR/$tdir
2662
2663         pool=$($LFS getstripe -p -d $DIR/$tdir)
2664
2665         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2666 }
2667 run_test 27G "Clear OST pool from stripe"
2668
2669 test_27H() {
2670         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2671                 skip "Need MDS version newer than 2.11.54"
2672         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2673         test_mkdir $DIR/$tdir
2674         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2675         touch $DIR/$tdir/$tfile
2676         $LFS getstripe -c $DIR/$tdir/$tfile
2677         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2678                 error "two-stripe file doesn't have two stripes"
2679
2680         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2681         $LFS getstripe -y $DIR/$tdir/$tfile
2682         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2683              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2684                 error "expected l_ost_idx: [02]$ not matched"
2685
2686         # make sure ost list has been cleared
2687         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2688         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2689                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2690         touch $DIR/$tdir/f3
2691         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2692 }
2693 run_test 27H "Set specific OSTs stripe"
2694
2695 test_27I() {
2696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2698         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2699                 skip "Need MDS version newer than 2.12.52"
2700         local pool=$TESTNAME
2701         local ostrange="1 1 1"
2702
2703         save_layout_restore_at_exit $MOUNT
2704         $LFS setstripe -c 2 -i 0 $MOUNT
2705         pool_add $pool || error "pool_add failed"
2706         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2707         test_mkdir $DIR/$tdir
2708         $LFS setstripe -p $pool $DIR/$tdir
2709         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2710         $LFS getstripe $DIR/$tdir/$tfile
2711 }
2712 run_test 27I "check that root dir striping does not break parent dir one"
2713
2714 test_27J() {
2715         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2716                 skip "Need MDS version newer than 2.12.51"
2717
2718         test_mkdir $DIR/$tdir
2719         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2720         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2721
2722         # create foreign file (raw way)
2723         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2724                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2725
2726         # verify foreign file (raw way)
2727         parse_foreign_file -f $DIR/$tdir/$tfile |
2728                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2729                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2730         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2731                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2732         parse_foreign_file -f $DIR/$tdir/$tfile |
2733                 grep "lov_foreign_size: 73" ||
2734                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2735         parse_foreign_file -f $DIR/$tdir/$tfile |
2736                 grep "lov_foreign_type: 1" ||
2737                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2738         parse_foreign_file -f $DIR/$tdir/$tfile |
2739                 grep "lov_foreign_flags: 0x0000DA08" ||
2740                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2741         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2742                 grep "lov_foreign_value: 0x" |
2743                 sed -e 's/lov_foreign_value: 0x//')
2744         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2745         [[ $lov = ${lov2// /} ]] ||
2746                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2747
2748         # create foreign file (lfs + API)
2749         $LFS setstripe --foreign=daos --flags 0xda08 \
2750                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2751                 error "$DIR/$tdir/${tfile}2: create failed"
2752
2753         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2754                 grep "lfm_magic:.*0x0BD70BD0" ||
2755                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2756         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2757         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2758                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2759         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2760                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2761         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2762                 grep "lfm_flags:.*0x0000DA08" ||
2763                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2764         $LFS getstripe $DIR/$tdir/${tfile}2 |
2765                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2766                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2767
2768         # modify striping should fail
2769         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2770                 error "$DIR/$tdir/$tfile: setstripe should fail"
2771         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2772                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2773
2774         # R/W should fail
2775         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2776         cat $DIR/$tdir/${tfile}2 &&
2777                 error "$DIR/$tdir/${tfile}2: read should fail"
2778         cat /etc/passwd > $DIR/$tdir/$tfile &&
2779                 error "$DIR/$tdir/$tfile: write should fail"
2780         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2781                 error "$DIR/$tdir/${tfile}2: write should fail"
2782
2783         # chmod should work
2784         chmod 222 $DIR/$tdir/$tfile ||
2785                 error "$DIR/$tdir/$tfile: chmod failed"
2786         chmod 222 $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: chmod failed"
2788
2789         # chown should work
2790         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2791                 error "$DIR/$tdir/$tfile: chown failed"
2792         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2793                 error "$DIR/$tdir/${tfile}2: chown failed"
2794
2795         # rename should work
2796         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2797                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2798         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2799                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2800
2801         #remove foreign file
2802         rm $DIR/$tdir/${tfile}.new ||
2803                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2804         rm $DIR/$tdir/${tfile}2.new ||
2805                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2806 }
2807 run_test 27J "basic ops on file with foreign LOV"
2808
2809 test_27K() {
2810         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2811                 skip "Need MDS version newer than 2.12.49"
2812
2813         test_mkdir $DIR/$tdir
2814         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2815         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2816
2817         # create foreign dir (raw way)
2818         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2819                 error "create_foreign_dir FAILED"
2820
2821         # verify foreign dir (raw way)
2822         parse_foreign_dir -d $DIR/$tdir/$tdir |
2823                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2824                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2825         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2826                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2827         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2828                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2829         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2830                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2831         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2832                 grep "lmv_foreign_value: 0x" |
2833                 sed 's/lmv_foreign_value: 0x//')
2834         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2835                 sed 's/ //g')
2836         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2837
2838         # create foreign dir (lfs + API)
2839         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2840                 $DIR/$tdir/${tdir}2 ||
2841                 error "$DIR/$tdir/${tdir}2: create failed"
2842
2843         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2844                 grep "lfm_magic:.*0x0CD50CD0" ||
2845                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2846         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2847         # - sizeof(lfm_type) - sizeof(lfm_flags)
2848         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2849                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2850         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2851                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2852         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2853                 grep "lfm_flags:.*0x0000DA05" ||
2854                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2855         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2856                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2857                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2858
2859         # file create in dir should fail
2860         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2861         touch $DIR/$tdir/${tdir}2/$tfile &&
2862                 "$DIR/${tdir}2: file create should fail"
2863
2864         # chmod should work
2865         chmod 777 $DIR/$tdir/$tdir ||
2866                 error "$DIR/$tdir: chmod failed"
2867         chmod 777 $DIR/$tdir/${tdir}2 ||
2868                 error "$DIR/${tdir}2: chmod failed"
2869
2870         # chown should work
2871         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2872                 error "$DIR/$tdir: chown failed"
2873         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2874                 error "$DIR/${tdir}2: chown failed"
2875
2876         # rename should work
2877         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2878                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2879         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2880                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2881
2882         #remove foreign dir
2883         rmdir $DIR/$tdir/${tdir}.new ||
2884                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2885         rmdir $DIR/$tdir/${tdir}2.new ||
2886                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2887 }
2888 run_test 27K "basic ops on dir with foreign LMV"
2889
2890 test_27L() {
2891         remote_mds_nodsh && skip "remote MDS with nodsh"
2892
2893         local POOL=${POOL:-$TESTNAME}
2894
2895         pool_add $POOL || error "pool_add failed"
2896
2897         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2898                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2899                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2900 }
2901 run_test 27L "lfs pool_list gives correct pool name"
2902
2903 test_27M() {
2904         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2905                 skip "Need MDS version >= than 2.12.57"
2906         remote_mds_nodsh && skip "remote MDS with nodsh"
2907         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2908
2909         test_mkdir $DIR/$tdir
2910
2911         # Set default striping on directory
2912         $LFS setstripe -C 4 $DIR/$tdir
2913
2914         echo 1 > $DIR/$tdir/${tfile}.1
2915         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2916         local setcount=4
2917         [ $count -eq $setcount ] ||
2918                 error "(1) stripe count $count, should be $setcount"
2919
2920         # Capture existing append_stripe_count setting for restore
2921         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2922         local mdts=$(comma_list $(mdts_nodes))
2923         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2924
2925         local appendcount=$orig_count
2926         echo 1 >> $DIR/$tdir/${tfile}.2_append
2927         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2928         [ $count -eq $appendcount ] ||
2929                 error "(2)stripe count $count, should be $appendcount for append"
2930
2931         # Disable O_APPEND striping, verify it works
2932         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2933
2934         # Should now get the default striping, which is 4
2935         setcount=4
2936         echo 1 >> $DIR/$tdir/${tfile}.3_append
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2938         [ $count -eq $setcount ] ||
2939                 error "(3) stripe count $count, should be $setcount"
2940
2941         # Try changing the stripe count for append files
2942         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2943
2944         # Append striping is now 2 (directory default is still 4)
2945         appendcount=2
2946         echo 1 >> $DIR/$tdir/${tfile}.4_append
2947         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2948         [ $count -eq $appendcount ] ||
2949                 error "(4) stripe count $count, should be $appendcount for append"
2950
2951         # Test append stripe count of -1
2952         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2953         appendcount=$OSTCOUNT
2954         echo 1 >> $DIR/$tdir/${tfile}.5
2955         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2956         [ $count -eq $appendcount ] ||
2957                 error "(5) stripe count $count, should be $appendcount for append"
2958
2959         # Set append striping back to default of 1
2960         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2961
2962         # Try a new default striping, PFL + DOM
2963         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2964
2965         # Create normal DOM file, DOM returns stripe count == 0
2966         setcount=0
2967         touch $DIR/$tdir/${tfile}.6
2968         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2969         [ $count -eq $setcount ] ||
2970                 error "(6) stripe count $count, should be $setcount"
2971
2972         # Show
2973         appendcount=1
2974         echo 1 >> $DIR/$tdir/${tfile}.7_append
2975         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2976         [ $count -eq $appendcount ] ||
2977                 error "(7) stripe count $count, should be $appendcount for append"
2978
2979         # Clean up DOM layout
2980         $LFS setstripe -d $DIR/$tdir
2981
2982         # Now test that append striping works when layout is from root
2983         $LFS setstripe -c 2 $MOUNT
2984         # Make a special directory for this
2985         mkdir $DIR/${tdir}/${tdir}.2
2986         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2987
2988         # Verify for normal file
2989         setcount=2
2990         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2991         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2992         [ $count -eq $setcount ] ||
2993                 error "(8) stripe count $count, should be $setcount"
2994
2995         appendcount=1
2996         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2997         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2998         [ $count -eq $appendcount ] ||
2999                 error "(9) stripe count $count, should be $appendcount for append"
3000
3001         # Now test O_APPEND striping with pools
3002         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3003         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3004
3005         # Create the pool
3006         pool_add $TESTNAME || error "pool creation failed"
3007         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3008
3009         echo 1 >> $DIR/$tdir/${tfile}.10_append
3010
3011         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3012         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3013
3014         # Check that count is still correct
3015         appendcount=1
3016         echo 1 >> $DIR/$tdir/${tfile}.11_append
3017         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3018         [ $count -eq $appendcount ] ||
3019                 error "(11) stripe count $count, should be $appendcount for append"
3020
3021         # Disable O_APPEND stripe count, verify pool works separately
3022         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3023
3024         echo 1 >> $DIR/$tdir/${tfile}.12_append
3025
3026         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3027         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3028
3029         # Remove pool setting, verify it's not applied
3030         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3031
3032         echo 1 >> $DIR/$tdir/${tfile}.13_append
3033
3034         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3035         [ "$pool" = "" ] || error "(13) pool found: $pool"
3036 }
3037 run_test 27M "test O_APPEND striping"
3038
3039 test_27N() {
3040         combined_mgs_mds && skip "needs separate MGS/MDT"
3041
3042         pool_add $TESTNAME || error "pool_add failed"
3043         do_facet mgs "$LCTL pool_list $FSNAME" |
3044                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3045                 error "lctl pool_list on MGS failed"
3046 }
3047 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3048
3049 # createtest also checks that device nodes are created and
3050 # then visible correctly (#2091)
3051 test_28() { # bug 2091
3052         test_mkdir $DIR/d28
3053         $CREATETEST $DIR/d28/ct || error "createtest failed"
3054 }
3055 run_test 28 "create/mknod/mkdir with bad file types ============"
3056
3057 test_29() {
3058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3059
3060         sync; sleep 1; sync # flush out any dirty pages from previous tests
3061         cancel_lru_locks
3062         test_mkdir $DIR/d29
3063         touch $DIR/d29/foo
3064         log 'first d29'
3065         ls -l $DIR/d29
3066
3067         declare -i LOCKCOUNTORIG=0
3068         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3069                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3070         done
3071         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3072
3073         declare -i LOCKUNUSEDCOUNTORIG=0
3074         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3075                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3076         done
3077
3078         log 'second d29'
3079         ls -l $DIR/d29
3080         log 'done'
3081
3082         declare -i LOCKCOUNTCURRENT=0
3083         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3084                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3085         done
3086
3087         declare -i LOCKUNUSEDCOUNTCURRENT=0
3088         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3089                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3090         done
3091
3092         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3093                 $LCTL set_param -n ldlm.dump_namespaces ""
3094                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3095                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3096                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3097                 return 2
3098         fi
3099         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3100                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3101                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3102                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3103                 return 3
3104         fi
3105 }
3106 run_test 29 "IT_GETATTR regression  ============================"
3107
3108 test_30a() { # was test_30
3109         cp $(which ls) $DIR || cp /bin/ls $DIR
3110         $DIR/ls / || error "Can't execute binary from lustre"
3111         rm $DIR/ls
3112 }
3113 run_test 30a "execute binary from Lustre (execve) =============="
3114
3115 test_30b() {
3116         cp `which ls` $DIR || cp /bin/ls $DIR
3117         chmod go+rx $DIR/ls
3118         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3119         rm $DIR/ls
3120 }
3121 run_test 30b "execute binary from Lustre as non-root ==========="
3122
3123 test_30c() { # b=22376
3124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3125
3126         cp $(which ls) $DIR || cp /bin/ls $DIR
3127         chmod a-rw $DIR/ls
3128         cancel_lru_locks mdc
3129         cancel_lru_locks osc
3130         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3131         rm -f $DIR/ls
3132 }
3133 run_test 30c "execute binary from Lustre without read perms ===="
3134
3135 test_30d() {
3136         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3137
3138         for i in {1..10}; do
3139                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3140                 local PID=$!
3141                 sleep 1
3142                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3143                 wait $PID || error "executing dd from Lustre failed"
3144                 rm -f $DIR/$tfile
3145         done
3146
3147         rm -f $DIR/dd
3148 }
3149 run_test 30d "execute binary from Lustre while clear locks"
3150
3151 test_31a() {
3152         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3153         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3154 }
3155 run_test 31a "open-unlink file =================================="
3156
3157 test_31b() {
3158         touch $DIR/f31 || error "touch $DIR/f31 failed"
3159         ln $DIR/f31 $DIR/f31b || error "ln failed"
3160         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3161         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3162 }
3163 run_test 31b "unlink file with multiple links while open ======="
3164
3165 test_31c() {
3166         touch $DIR/f31 || error "touch $DIR/f31 failed"
3167         ln $DIR/f31 $DIR/f31c || error "ln failed"
3168         multiop_bg_pause $DIR/f31 O_uc ||
3169                 error "multiop_bg_pause for $DIR/f31 failed"
3170         MULTIPID=$!
3171         $MULTIOP $DIR/f31c Ouc
3172         kill -USR1 $MULTIPID
3173         wait $MULTIPID
3174 }
3175 run_test 31c "open-unlink file with multiple links ============="
3176
3177 test_31d() {
3178         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3179         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3180 }
3181 run_test 31d "remove of open directory ========================="
3182
3183 test_31e() { # bug 2904
3184         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3185 }
3186 run_test 31e "remove of open non-empty directory ==============="
3187
3188 test_31f() { # bug 4554
3189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3190
3191         set -vx
3192         test_mkdir $DIR/d31f
3193         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3194         cp /etc/hosts $DIR/d31f
3195         ls -l $DIR/d31f
3196         $LFS getstripe $DIR/d31f/hosts
3197         multiop_bg_pause $DIR/d31f D_c || return 1
3198         MULTIPID=$!
3199
3200         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3201         test_mkdir $DIR/d31f
3202         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3203         cp /etc/hosts $DIR/d31f
3204         ls -l $DIR/d31f
3205         $LFS getstripe $DIR/d31f/hosts
3206         multiop_bg_pause $DIR/d31f D_c || return 1
3207         MULTIPID2=$!
3208
3209         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3210         wait $MULTIPID || error "first opendir $MULTIPID failed"
3211
3212         sleep 6
3213
3214         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3215         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3216         set +vx
3217 }
3218 run_test 31f "remove of open directory with open-unlink file ==="
3219
3220 test_31g() {
3221         echo "-- cross directory link --"
3222         test_mkdir -c1 $DIR/${tdir}ga
3223         test_mkdir -c1 $DIR/${tdir}gb
3224         touch $DIR/${tdir}ga/f
3225         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3226         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3227         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3228         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3229         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3230 }
3231 run_test 31g "cross directory link==============="
3232
3233 test_31h() {
3234         echo "-- cross directory link --"
3235         test_mkdir -c1 $DIR/${tdir}
3236         test_mkdir -c1 $DIR/${tdir}/dir
3237         touch $DIR/${tdir}/f
3238         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3239         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3240         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3241         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3242         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3243 }
3244 run_test 31h "cross directory link under child==============="
3245
3246 test_31i() {
3247         echo "-- cross directory link --"
3248         test_mkdir -c1 $DIR/$tdir
3249         test_mkdir -c1 $DIR/$tdir/dir
3250         touch $DIR/$tdir/dir/f
3251         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3252         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3253         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3254         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3255         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3256 }
3257 run_test 31i "cross directory link under parent==============="
3258
3259 test_31j() {
3260         test_mkdir -c1 -p $DIR/$tdir
3261         test_mkdir -c1 -p $DIR/$tdir/dir1
3262         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3263         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3264         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3265         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3266         return 0
3267 }
3268 run_test 31j "link for directory==============="
3269
3270 test_31k() {
3271         test_mkdir -c1 -p $DIR/$tdir
3272         touch $DIR/$tdir/s
3273         touch $DIR/$tdir/exist
3274         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3275         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3276         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3277         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3278         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3279         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3280         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3281         return 0
3282 }
3283 run_test 31k "link to file: the same, non-existing, dir==============="
3284
3285 test_31m() {
3286         mkdir $DIR/d31m
3287         touch $DIR/d31m/s
3288         mkdir $DIR/d31m2
3289         touch $DIR/d31m2/exist
3290         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3291         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3292         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3293         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3294         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3295         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3296         return 0
3297 }
3298 run_test 31m "link to file: the same, non-existing, dir==============="
3299
3300 test_31n() {
3301         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3302         nlink=$(stat --format=%h $DIR/$tfile)
3303         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3304         local fd=$(free_fd)
3305         local cmd="exec $fd<$DIR/$tfile"
3306         eval $cmd
3307         cmd="exec $fd<&-"
3308         trap "eval $cmd" EXIT
3309         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3310         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3311         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3312         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3313         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3314         eval $cmd
3315 }
3316 run_test 31n "check link count of unlinked file"
3317
3318 link_one() {
3319         local tempfile=$(mktemp $1_XXXXXX)
3320         mlink $tempfile $1 2> /dev/null &&
3321                 echo "$BASHPID: link $tempfile to $1 succeeded"
3322         munlink $tempfile
3323 }
3324
3325 test_31o() { # LU-2901
3326         test_mkdir $DIR/$tdir
3327         for LOOP in $(seq 100); do
3328                 rm -f $DIR/$tdir/$tfile*
3329                 for THREAD in $(seq 8); do
3330                         link_one $DIR/$tdir/$tfile.$LOOP &
3331                 done
3332                 wait
3333                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3334                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3335                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3336                         break || true
3337         done
3338 }
3339 run_test 31o "duplicate hard links with same filename"
3340
3341 test_31p() {
3342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3343
3344         test_mkdir $DIR/$tdir
3345         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3346         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3347
3348         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3349                 error "open unlink test1 failed"
3350         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3351                 error "open unlink test2 failed"
3352
3353         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3354                 error "test1 still exists"
3355         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3356                 error "test2 still exists"
3357 }
3358 run_test 31p "remove of open striped directory"
3359
3360 test_31q() {
3361         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3362
3363         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3364         index=$($LFS getdirstripe -i $DIR/$tdir)
3365         [ $index -eq 3 ] || error "first stripe index $index != 3"
3366         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3367         [ $index -eq 1 ] || error "second stripe index $index != 1"
3368
3369         # when "-c <stripe_count>" is set, the number of MDTs specified after
3370         # "-i" should equal to the stripe count
3371         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3372 }
3373 run_test 31q "create striped directory on specific MDTs"
3374
3375 cleanup_test32_mount() {
3376         local rc=0
3377         trap 0
3378         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3379         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3380         losetup -d $loopdev || true
3381         rm -rf $DIR/$tdir
3382         return $rc
3383 }
3384
3385 test_32a() {
3386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3387
3388         echo "== more mountpoints and symlinks ================="
3389         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3390         trap cleanup_test32_mount EXIT
3391         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3392         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3393                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3394         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3395                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3396         cleanup_test32_mount
3397 }
3398 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3399
3400 test_32b() {
3401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3402
3403         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3404         trap cleanup_test32_mount EXIT
3405         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3406         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3407                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3408         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3409                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3410         cleanup_test32_mount
3411 }
3412 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3413
3414 test_32c() {
3415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3416
3417         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3418         trap cleanup_test32_mount EXIT
3419         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3420         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3421                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3422         test_mkdir -p $DIR/$tdir/d2/test_dir
3423         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3424                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3425         cleanup_test32_mount
3426 }
3427 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3428
3429 test_32d() {
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3433         trap cleanup_test32_mount EXIT
3434         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3435         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3436                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3437         test_mkdir -p $DIR/$tdir/d2/test_dir
3438         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3439                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3440         cleanup_test32_mount
3441 }
3442 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3443
3444 test_32e() {
3445         rm -fr $DIR/$tdir
3446         test_mkdir -p $DIR/$tdir/tmp
3447         local tmp_dir=$DIR/$tdir/tmp
3448         ln -s $DIR/$tdir $tmp_dir/symlink11
3449         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3450         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3451         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3452 }
3453 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3454
3455 test_32f() {
3456         rm -fr $DIR/$tdir
3457         test_mkdir -p $DIR/$tdir/tmp
3458         local tmp_dir=$DIR/$tdir/tmp
3459         ln -s $DIR/$tdir $tmp_dir/symlink11
3460         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3461         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3462         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3463 }
3464 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3465
3466 test_32g() {
3467         local tmp_dir=$DIR/$tdir/tmp
3468         test_mkdir -p $tmp_dir
3469         test_mkdir $DIR/${tdir}2
3470         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3471         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3472         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3473         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3474         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3475         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3476 }
3477 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3478
3479 test_32h() {
3480         rm -fr $DIR/$tdir $DIR/${tdir}2
3481         tmp_dir=$DIR/$tdir/tmp
3482         test_mkdir -p $tmp_dir
3483         test_mkdir $DIR/${tdir}2
3484         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3485         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3486         ls $tmp_dir/symlink12 || error "listing symlink12"
3487         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3488 }
3489 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3490
3491 test_32i() {
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3495         trap cleanup_test32_mount EXIT
3496         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3497         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3498                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3499         touch $DIR/$tdir/test_file
3500         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3501                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3502         cleanup_test32_mount
3503 }
3504 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3505
3506 test_32j() {
3507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3508
3509         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3510         trap cleanup_test32_mount EXIT
3511         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3512         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3513                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3514         touch $DIR/$tdir/test_file
3515         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3516                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3517         cleanup_test32_mount
3518 }
3519 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3520
3521 test_32k() {
3522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3523
3524         rm -fr $DIR/$tdir
3525         trap cleanup_test32_mount EXIT
3526         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3527         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3528                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3529         test_mkdir -p $DIR/$tdir/d2
3530         touch $DIR/$tdir/d2/test_file || error "touch failed"
3531         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3532                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3533         cleanup_test32_mount
3534 }
3535 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3536
3537 test_32l() {
3538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3539
3540         rm -fr $DIR/$tdir
3541         trap cleanup_test32_mount EXIT
3542         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3543         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3544                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3545         test_mkdir -p $DIR/$tdir/d2
3546         touch $DIR/$tdir/d2/test_file || error "touch failed"
3547         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3548                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3549         cleanup_test32_mount
3550 }
3551 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3552
3553 test_32m() {
3554         rm -fr $DIR/d32m
3555         test_mkdir -p $DIR/d32m/tmp
3556         TMP_DIR=$DIR/d32m/tmp
3557         ln -s $DIR $TMP_DIR/symlink11
3558         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3559         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3560                 error "symlink11 not a link"
3561         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3562                 error "symlink01 not a link"
3563 }
3564 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3565
3566 test_32n() {
3567         rm -fr $DIR/d32n
3568         test_mkdir -p $DIR/d32n/tmp
3569         TMP_DIR=$DIR/d32n/tmp
3570         ln -s $DIR $TMP_DIR/symlink11
3571         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3572         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3573         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3574 }
3575 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3576
3577 test_32o() {
3578         touch $DIR/$tfile
3579         test_mkdir -p $DIR/d32o/tmp
3580         TMP_DIR=$DIR/d32o/tmp
3581         ln -s $DIR/$tfile $TMP_DIR/symlink12
3582         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3583         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3584                 error "symlink12 not a link"
3585         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3586         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3587                 error "$DIR/d32o/tmp/symlink12 not file type"
3588         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3589                 error "$DIR/d32o/symlink02 not file type"
3590 }
3591 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3592
3593 test_32p() {
3594         log 32p_1
3595         rm -fr $DIR/d32p
3596         log 32p_2
3597         rm -f $DIR/$tfile
3598         log 32p_3
3599         touch $DIR/$tfile
3600         log 32p_4
3601         test_mkdir -p $DIR/d32p/tmp
3602         log 32p_5
3603         TMP_DIR=$DIR/d32p/tmp
3604         log 32p_6
3605         ln -s $DIR/$tfile $TMP_DIR/symlink12
3606         log 32p_7
3607         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3608         log 32p_8
3609         cat $DIR/d32p/tmp/symlink12 ||
3610                 error "Can't open $DIR/d32p/tmp/symlink12"
3611         log 32p_9
3612         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3613         log 32p_10
3614 }
3615 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3616
3617 test_32q() {
3618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3619
3620         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3621         trap cleanup_test32_mount EXIT
3622         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3623         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3624         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3625                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3626         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3627         cleanup_test32_mount
3628 }
3629 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3630
3631 test_32r() {
3632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3633
3634         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3635         trap cleanup_test32_mount EXIT
3636         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3637         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3638         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3639                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3640         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3641         cleanup_test32_mount
3642 }
3643 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3644
3645 test_33aa() {
3646         rm -f $DIR/$tfile
3647         touch $DIR/$tfile
3648         chmod 444 $DIR/$tfile
3649         chown $RUNAS_ID $DIR/$tfile
3650         log 33_1
3651         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3652         log 33_2
3653 }
3654 run_test 33aa "write file with mode 444 (should return error)"
3655
3656 test_33a() {
3657         rm -fr $DIR/$tdir
3658         test_mkdir $DIR/$tdir
3659         chown $RUNAS_ID $DIR/$tdir
3660         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3661                 error "$RUNAS create $tdir/$tfile failed"
3662         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3663                 error "open RDWR" || true
3664 }
3665 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3666
3667 test_33b() {
3668         rm -fr $DIR/$tdir
3669         test_mkdir $DIR/$tdir
3670         chown $RUNAS_ID $DIR/$tdir
3671         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3672 }
3673 run_test 33b "test open file with malformed flags (No panic)"
3674
3675 test_33c() {
3676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3677         remote_ost_nodsh && skip "remote OST with nodsh"
3678
3679         local ostnum
3680         local ostname
3681         local write_bytes
3682         local all_zeros
3683
3684         all_zeros=:
3685         rm -fr $DIR/$tdir
3686         test_mkdir $DIR/$tdir
3687         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3688
3689         sync
3690         for ostnum in $(seq $OSTCOUNT); do
3691                 # test-framework's OST numbering is one-based, while Lustre's
3692                 # is zero-based
3693                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                 # Parsing llobdstat's output sucks; we could grep the /proc
3695                 # path, but that's likely to not be as portable as using the
3696                 # llobdstat utility.  So we parse lctl output instead.
3697                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3698                         obdfilter/$ostname/stats |
3699                         awk '/^write_bytes/ {print $7}' )
3700                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3701                 if (( ${write_bytes:-0} > 0 ))
3702                 then
3703                         all_zeros=false
3704                         break;
3705                 fi
3706         done
3707
3708         $all_zeros || return 0
3709
3710         # Write four bytes
3711         echo foo > $DIR/$tdir/bar
3712         # Really write them
3713         sync
3714
3715         # Total up write_bytes after writing.  We'd better find non-zeros.
3716         for ostnum in $(seq $OSTCOUNT); do
3717                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3718                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3719                         obdfilter/$ostname/stats |
3720                         awk '/^write_bytes/ {print $7}' )
3721                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3722                 if (( ${write_bytes:-0} > 0 ))
3723                 then
3724                         all_zeros=false
3725                         break;
3726                 fi
3727         done
3728
3729         if $all_zeros
3730         then
3731                 for ostnum in $(seq $OSTCOUNT); do
3732                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3733                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3734                         do_facet ost$ostnum lctl get_param -n \
3735                                 obdfilter/$ostname/stats
3736                 done
3737                 error "OST not keeping write_bytes stats (b22312)"
3738         fi
3739 }
3740 run_test 33c "test llobdstat and write_bytes"
3741
3742 test_33d() {
3743         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3745
3746         local MDTIDX=1
3747         local remote_dir=$DIR/$tdir/remote_dir
3748
3749         test_mkdir $DIR/$tdir
3750         $LFS mkdir -i $MDTIDX $remote_dir ||
3751                 error "create remote directory failed"
3752
3753         touch $remote_dir/$tfile
3754         chmod 444 $remote_dir/$tfile
3755         chown $RUNAS_ID $remote_dir/$tfile
3756
3757         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3758
3759         chown $RUNAS_ID $remote_dir
3760         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3761                                         error "create" || true
3762         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3763                                     error "open RDWR" || true
3764         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3765 }
3766 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3767
3768 test_33e() {
3769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3770
3771         mkdir $DIR/$tdir
3772
3773         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3774         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3775         mkdir $DIR/$tdir/local_dir
3776
3777         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3778         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3779         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3780
3781         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3782                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3783
3784         rmdir $DIR/$tdir/* || error "rmdir failed"
3785
3786         umask 777
3787         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3788         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3789         mkdir $DIR/$tdir/local_dir
3790
3791         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3792         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3793         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3794
3795         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3796                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3797
3798         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3799
3800         umask 000
3801         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3802         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3803         mkdir $DIR/$tdir/local_dir
3804
3805         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3806         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3807         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3808
3809         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3810                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3811 }
3812 run_test 33e "mkdir and striped directory should have same mode"
3813
3814 cleanup_33f() {
3815         trap 0
3816         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3817 }
3818
3819 test_33f() {
3820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3821         remote_mds_nodsh && skip "remote MDS with nodsh"
3822
3823         mkdir $DIR/$tdir
3824         chmod go+rwx $DIR/$tdir
3825         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3826         trap cleanup_33f EXIT
3827
3828         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3829                 error "cannot create striped directory"
3830
3831         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3832                 error "cannot create files in striped directory"
3833
3834         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3835                 error "cannot remove files in striped directory"
3836
3837         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3838                 error "cannot remove striped directory"
3839
3840         cleanup_33f
3841 }
3842 run_test 33f "nonroot user can create, access, and remove a striped directory"
3843
3844 test_33g() {
3845         mkdir -p $DIR/$tdir/dir2
3846
3847         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3848         echo $err
3849         [[ $err =~ "exists" ]] || error "Not exists error"
3850 }
3851 run_test 33g "nonroot user create already existing root created file"
3852
3853 test_33h() {
3854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3855         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3856                 skip "Need MDS version at least 2.13.50"
3857
3858         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3859                 error "mkdir $tdir failed"
3860         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3861
3862         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3863         local index2
3864
3865         for fname in $DIR/$tdir/$tfile.bak \
3866                      $DIR/$tdir/$tfile.SAV \
3867                      $DIR/$tdir/$tfile.orig \
3868                      $DIR/$tdir/$tfile~; do
3869                 touch $fname  || error "touch $fname failed"
3870                 index2=$($LFS getstripe -m $fname)
3871                 [ $index -eq $index2 ] ||
3872                         error "$fname MDT index mismatch $index != $index2"
3873         done
3874
3875         local failed=0
3876         for i in {1..250}; do
3877                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3878                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3879                         touch $fname  || error "touch $fname failed"
3880                         index2=$($LFS getstripe -m $fname)
3881                         if [[ $index != $index2 ]]; then
3882                                 failed=$((failed + 1))
3883                                 echo "$fname MDT index mismatch $index != $index2"
3884                         fi
3885                 done
3886         done
3887         echo "$failed MDT index mismatches"
3888         (( failed < 20 )) || error "MDT index mismatch $failed times"
3889
3890 }
3891 run_test 33h "temp file is located on the same MDT as target"
3892
3893 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3894 test_34a() {
3895         rm -f $DIR/f34
3896         $MCREATE $DIR/f34 || error "mcreate failed"
3897         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3898                 error "getstripe failed"
3899         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3900         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3901                 error "getstripe failed"
3902         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3903                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3904 }
3905 run_test 34a "truncate file that has not been opened ==========="
3906
3907 test_34b() {
3908         [ ! -f $DIR/f34 ] && test_34a
3909         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3910                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3911         $OPENFILE -f O_RDONLY $DIR/f34
3912         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3913                 error "getstripe failed"
3914         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3915                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3916 }
3917 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3918
3919 test_34c() {
3920         [ ! -f $DIR/f34 ] && test_34a
3921         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3922                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3923         $OPENFILE -f O_RDWR $DIR/f34
3924         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3925                 error "$LFS getstripe failed"
3926         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3927                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3928 }
3929 run_test 34c "O_RDWR opening file-with-size works =============="
3930
3931 test_34d() {
3932         [ ! -f $DIR/f34 ] && test_34a
3933         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3934                 error "dd failed"
3935         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3936                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3937         rm $DIR/f34
3938 }
3939 run_test 34d "write to sparse file ============================="
3940
3941 test_34e() {
3942         rm -f $DIR/f34e
3943         $MCREATE $DIR/f34e || error "mcreate failed"
3944         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3945         $CHECKSTAT -s 1000 $DIR/f34e ||
3946                 error "Size of $DIR/f34e not equal to 1000 bytes"
3947         $OPENFILE -f O_RDWR $DIR/f34e
3948         $CHECKSTAT -s 1000 $DIR/f34e ||
3949                 error "Size of $DIR/f34e not equal to 1000 bytes"
3950 }
3951 run_test 34e "create objects, some with size and some without =="
3952
3953 test_34f() { # bug 6242, 6243
3954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3955
3956         SIZE34F=48000
3957         rm -f $DIR/f34f
3958         $MCREATE $DIR/f34f || error "mcreate failed"
3959         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3960         dd if=$DIR/f34f of=$TMP/f34f
3961         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3962         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3963         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3964         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3965         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3966 }
3967 run_test 34f "read from a file with no objects until EOF ======="
3968
3969 test_34g() {
3970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3971
3972         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3973                 error "dd failed"
3974         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3975         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3976                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3977         cancel_lru_locks osc
3978         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3979                 error "wrong size after lock cancel"
3980
3981         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3982         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3983                 error "expanding truncate failed"
3984         cancel_lru_locks osc
3985         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3986                 error "wrong expanded size after lock cancel"
3987 }
3988 run_test 34g "truncate long file ==============================="
3989
3990 test_34h() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         local gid=10
3994         local sz=1000
3995
3996         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3997         sync # Flush the cache so that multiop below does not block on cache
3998              # flush when getting the group lock
3999         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4000         MULTIPID=$!
4001
4002         # Since just timed wait is not good enough, let's do a sync write
4003         # that way we are sure enough time for a roundtrip + processing
4004         # passed + 2 seconds of extra margin.
4005         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4006         rm $DIR/${tfile}-1
4007         sleep 2
4008
4009         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4010                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4011                 kill -9 $MULTIPID
4012         fi
4013         wait $MULTIPID
4014         local nsz=`stat -c %s $DIR/$tfile`
4015         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4016 }
4017 run_test 34h "ftruncate file under grouplock should not block"
4018
4019 test_35a() {
4020         cp /bin/sh $DIR/f35a
4021         chmod 444 $DIR/f35a
4022         chown $RUNAS_ID $DIR/f35a
4023         $RUNAS $DIR/f35a && error || true
4024         rm $DIR/f35a
4025 }
4026 run_test 35a "exec file with mode 444 (should return and not leak)"
4027
4028 test_36a() {
4029         rm -f $DIR/f36
4030         utime $DIR/f36 || error "utime failed for MDS"
4031 }
4032 run_test 36a "MDS utime check (mknod, utime)"
4033
4034 test_36b() {
4035         echo "" > $DIR/f36
4036         utime $DIR/f36 || error "utime failed for OST"
4037 }
4038 run_test 36b "OST utime check (open, utime)"
4039
4040 test_36c() {
4041         rm -f $DIR/d36/f36
4042         test_mkdir $DIR/d36
4043         chown $RUNAS_ID $DIR/d36
4044         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4045 }
4046 run_test 36c "non-root MDS utime check (mknod, utime)"
4047
4048 test_36d() {
4049         [ ! -d $DIR/d36 ] && test_36c
4050         echo "" > $DIR/d36/f36
4051         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4052 }
4053 run_test 36d "non-root OST utime check (open, utime)"
4054
4055 test_36e() {
4056         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4057
4058         test_mkdir $DIR/$tdir
4059         touch $DIR/$tdir/$tfile
4060         $RUNAS utime $DIR/$tdir/$tfile &&
4061                 error "utime worked, expected failure" || true
4062 }
4063 run_test 36e "utime on non-owned file (should return error)"
4064
4065 subr_36fh() {
4066         local fl="$1"
4067         local LANG_SAVE=$LANG
4068         local LC_LANG_SAVE=$LC_LANG
4069         export LANG=C LC_LANG=C # for date language
4070
4071         DATESTR="Dec 20  2000"
4072         test_mkdir $DIR/$tdir
4073         lctl set_param fail_loc=$fl
4074         date; date +%s
4075         cp /etc/hosts $DIR/$tdir/$tfile
4076         sync & # write RPC generated with "current" inode timestamp, but delayed
4077         sleep 1
4078         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4079         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4080         cancel_lru_locks $OSC
4081         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4082         date; date +%s
4083         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4084                 echo "BEFORE: $LS_BEFORE" && \
4085                 echo "AFTER : $LS_AFTER" && \
4086                 echo "WANT  : $DATESTR" && \
4087                 error "$DIR/$tdir/$tfile timestamps changed" || true
4088
4089         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4090 }
4091
4092 test_36f() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4096         subr_36fh "0x80000214"
4097 }
4098 run_test 36f "utime on file racing with OST BRW write =========="
4099
4100 test_36g() {
4101         remote_ost_nodsh && skip "remote OST with nodsh"
4102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4103         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4104                 skip "Need MDS version at least 2.12.51"
4105
4106         local fmd_max_age
4107         local fmd
4108         local facet="ost1"
4109         local tgt="obdfilter"
4110
4111         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4112
4113         test_mkdir $DIR/$tdir
4114         fmd_max_age=$(do_facet $facet \
4115                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4116                 head -n 1")
4117
4118         echo "FMD max age: ${fmd_max_age}s"
4119         touch $DIR/$tdir/$tfile
4120         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4121                 gawk '{cnt=cnt+$1}  END{print cnt}')
4122         echo "FMD before: $fmd"
4123         [[ $fmd == 0 ]] &&
4124                 error "FMD wasn't create by touch"
4125         sleep $((fmd_max_age + 12))
4126         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4127                 gawk '{cnt=cnt+$1}  END{print cnt}')
4128         echo "FMD after: $fmd"
4129         [[ $fmd == 0 ]] ||
4130                 error "FMD wasn't expired by ping"
4131 }
4132 run_test 36g "FMD cache expiry ====================="
4133
4134 test_36h() {
4135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4136
4137         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4138         subr_36fh "0x80000227"
4139 }
4140 run_test 36h "utime on file racing with OST BRW write =========="
4141
4142 test_36i() {
4143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4144
4145         test_mkdir $DIR/$tdir
4146         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4147
4148         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4149         local new_mtime=$((mtime + 200))
4150
4151         #change Modify time of striped dir
4152         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4153                         error "change mtime failed"
4154
4155         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4156
4157         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4158 }
4159 run_test 36i "change mtime on striped directory"
4160
4161 # test_37 - duplicate with tests 32q 32r
4162
4163 test_38() {
4164         local file=$DIR/$tfile
4165         touch $file
4166         openfile -f O_DIRECTORY $file
4167         local RC=$?
4168         local ENOTDIR=20
4169         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4170         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4171 }
4172 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4173
4174 test_39a() { # was test_39
4175         touch $DIR/$tfile
4176         touch $DIR/${tfile}2
4177 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4178 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4179 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4180         sleep 2
4181         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4182         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4183                 echo "mtime"
4184                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4185                 echo "atime"
4186                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4187                 echo "ctime"
4188                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4189                 error "O_TRUNC didn't change timestamps"
4190         fi
4191 }
4192 run_test 39a "mtime changed on create"
4193
4194 test_39b() {
4195         test_mkdir -c1 $DIR/$tdir
4196         cp -p /etc/passwd $DIR/$tdir/fopen
4197         cp -p /etc/passwd $DIR/$tdir/flink
4198         cp -p /etc/passwd $DIR/$tdir/funlink
4199         cp -p /etc/passwd $DIR/$tdir/frename
4200         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4201
4202         sleep 1
4203         echo "aaaaaa" >> $DIR/$tdir/fopen
4204         echo "aaaaaa" >> $DIR/$tdir/flink
4205         echo "aaaaaa" >> $DIR/$tdir/funlink
4206         echo "aaaaaa" >> $DIR/$tdir/frename
4207
4208         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4209         local link_new=`stat -c %Y $DIR/$tdir/flink`
4210         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4211         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4212
4213         cat $DIR/$tdir/fopen > /dev/null
4214         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4215         rm -f $DIR/$tdir/funlink2
4216         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4217
4218         for (( i=0; i < 2; i++ )) ; do
4219                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4220                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4221                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4222                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4223
4224                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4225                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4226                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4227                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4228
4229                 cancel_lru_locks $OSC
4230                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4231         done
4232 }
4233 run_test 39b "mtime change on open, link, unlink, rename  ======"
4234
4235 # this should be set to past
4236 TEST_39_MTIME=`date -d "1 year ago" +%s`
4237
4238 # bug 11063
4239 test_39c() {
4240         touch $DIR1/$tfile
4241         sleep 2
4242         local mtime0=`stat -c %Y $DIR1/$tfile`
4243
4244         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4245         local mtime1=`stat -c %Y $DIR1/$tfile`
4246         [ "$mtime1" = $TEST_39_MTIME ] || \
4247                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4248
4249         local d1=`date +%s`
4250         echo hello >> $DIR1/$tfile
4251         local d2=`date +%s`
4252         local mtime2=`stat -c %Y $DIR1/$tfile`
4253         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4254                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4255
4256         mv $DIR1/$tfile $DIR1/$tfile-1
4257
4258         for (( i=0; i < 2; i++ )) ; do
4259                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4260                 [ "$mtime2" = "$mtime3" ] || \
4261                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4262
4263                 cancel_lru_locks $OSC
4264                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4265         done
4266 }
4267 run_test 39c "mtime change on rename ==========================="
4268
4269 # bug 21114
4270 test_39d() {
4271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4272
4273         touch $DIR1/$tfile
4274         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4275
4276         for (( i=0; i < 2; i++ )) ; do
4277                 local mtime=`stat -c %Y $DIR1/$tfile`
4278                 [ $mtime = $TEST_39_MTIME ] || \
4279                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4280
4281                 cancel_lru_locks $OSC
4282                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4283         done
4284 }
4285 run_test 39d "create, utime, stat =============================="
4286
4287 # bug 21114
4288 test_39e() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         touch $DIR1/$tfile
4292         local mtime1=`stat -c %Y $DIR1/$tfile`
4293
4294         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4295
4296         for (( i=0; i < 2; i++ )) ; do
4297                 local mtime2=`stat -c %Y $DIR1/$tfile`
4298                 [ $mtime2 = $TEST_39_MTIME ] || \
4299                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4300
4301                 cancel_lru_locks $OSC
4302                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4303         done
4304 }
4305 run_test 39e "create, stat, utime, stat ========================"
4306
4307 # bug 21114
4308 test_39f() {
4309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4310
4311         touch $DIR1/$tfile
4312         mtime1=`stat -c %Y $DIR1/$tfile`
4313
4314         sleep 2
4315         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4316
4317         for (( i=0; i < 2; i++ )) ; do
4318                 local mtime2=`stat -c %Y $DIR1/$tfile`
4319                 [ $mtime2 = $TEST_39_MTIME ] || \
4320                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4321
4322                 cancel_lru_locks $OSC
4323                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4324         done
4325 }
4326 run_test 39f "create, stat, sleep, utime, stat ================="
4327
4328 # bug 11063
4329 test_39g() {
4330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4331
4332         echo hello >> $DIR1/$tfile
4333         local mtime1=`stat -c %Y $DIR1/$tfile`
4334
4335         sleep 2
4336         chmod o+r $DIR1/$tfile
4337
4338         for (( i=0; i < 2; i++ )) ; do
4339                 local mtime2=`stat -c %Y $DIR1/$tfile`
4340                 [ "$mtime1" = "$mtime2" ] || \
4341                         error "lost mtime: $mtime2, should be $mtime1"
4342
4343                 cancel_lru_locks $OSC
4344                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4345         done
4346 }
4347 run_test 39g "write, chmod, stat ==============================="
4348
4349 # bug 11063
4350 test_39h() {
4351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4352
4353         touch $DIR1/$tfile
4354         sleep 1
4355
4356         local d1=`date`
4357         echo hello >> $DIR1/$tfile
4358         local mtime1=`stat -c %Y $DIR1/$tfile`
4359
4360         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4361         local d2=`date`
4362         if [ "$d1" != "$d2" ]; then
4363                 echo "write and touch not within one second"
4364         else
4365                 for (( i=0; i < 2; i++ )) ; do
4366                         local mtime2=`stat -c %Y $DIR1/$tfile`
4367                         [ "$mtime2" = $TEST_39_MTIME ] || \
4368                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4369
4370                         cancel_lru_locks $OSC
4371                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4372                 done
4373         fi
4374 }
4375 run_test 39h "write, utime within one second, stat ============="
4376
4377 test_39i() {
4378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4379
4380         touch $DIR1/$tfile
4381         sleep 1
4382
4383         echo hello >> $DIR1/$tfile
4384         local mtime1=`stat -c %Y $DIR1/$tfile`
4385
4386         mv $DIR1/$tfile $DIR1/$tfile-1
4387
4388         for (( i=0; i < 2; i++ )) ; do
4389                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4390
4391                 [ "$mtime1" = "$mtime2" ] || \
4392                         error "lost mtime: $mtime2, should be $mtime1"
4393
4394                 cancel_lru_locks $OSC
4395                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4396         done
4397 }
4398 run_test 39i "write, rename, stat =============================="
4399
4400 test_39j() {
4401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4402
4403         start_full_debug_logging
4404         touch $DIR1/$tfile
4405         sleep 1
4406
4407         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4408         lctl set_param fail_loc=0x80000412
4409         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4410                 error "multiop failed"
4411         local multipid=$!
4412         local mtime1=`stat -c %Y $DIR1/$tfile`
4413
4414         mv $DIR1/$tfile $DIR1/$tfile-1
4415
4416         kill -USR1 $multipid
4417         wait $multipid || error "multiop close failed"
4418
4419         for (( i=0; i < 2; i++ )) ; do
4420                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4421                 [ "$mtime1" = "$mtime2" ] ||
4422                         error "mtime is lost on close: $mtime2, " \
4423                               "should be $mtime1"
4424
4425                 cancel_lru_locks
4426                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4427         done
4428         lctl set_param fail_loc=0
4429         stop_full_debug_logging
4430 }
4431 run_test 39j "write, rename, close, stat ======================="
4432
4433 test_39k() {
4434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4435
4436         touch $DIR1/$tfile
4437         sleep 1
4438
4439         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4440         local multipid=$!
4441         local mtime1=`stat -c %Y $DIR1/$tfile`
4442
4443         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4444
4445         kill -USR1 $multipid
4446         wait $multipid || error "multiop close failed"
4447
4448         for (( i=0; i < 2; i++ )) ; do
4449                 local mtime2=`stat -c %Y $DIR1/$tfile`
4450
4451                 [ "$mtime2" = $TEST_39_MTIME ] || \
4452                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4453
4454                 cancel_lru_locks
4455                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4456         done
4457 }
4458 run_test 39k "write, utime, close, stat ========================"
4459
4460 # this should be set to future
4461 TEST_39_ATIME=`date -d "1 year" +%s`
4462
4463 test_39l() {
4464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4465         remote_mds_nodsh && skip "remote MDS with nodsh"
4466
4467         local atime_diff=$(do_facet $SINGLEMDS \
4468                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4469         rm -rf $DIR/$tdir
4470         mkdir -p $DIR/$tdir
4471
4472         # test setting directory atime to future
4473         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4474         local atime=$(stat -c %X $DIR/$tdir)
4475         [ "$atime" = $TEST_39_ATIME ] ||
4476                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4477
4478         # test setting directory atime from future to now
4479         local now=$(date +%s)
4480         touch -a -d @$now $DIR/$tdir
4481
4482         atime=$(stat -c %X $DIR/$tdir)
4483         [ "$atime" -eq "$now"  ] ||
4484                 error "atime is not updated from future: $atime, $now"
4485
4486         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4487         sleep 3
4488
4489         # test setting directory atime when now > dir atime + atime_diff
4490         local d1=$(date +%s)
4491         ls $DIR/$tdir
4492         local d2=$(date +%s)
4493         cancel_lru_locks mdc
4494         atime=$(stat -c %X $DIR/$tdir)
4495         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4496                 error "atime is not updated  : $atime, should be $d2"
4497
4498         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4499         sleep 3
4500
4501         # test not setting directory atime when now < dir atime + atime_diff
4502         ls $DIR/$tdir
4503         cancel_lru_locks mdc
4504         atime=$(stat -c %X $DIR/$tdir)
4505         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4506                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4507
4508         do_facet $SINGLEMDS \
4509                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4510 }
4511 run_test 39l "directory atime update ==========================="
4512
4513 test_39m() {
4514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4515
4516         touch $DIR1/$tfile
4517         sleep 2
4518         local far_past_mtime=$(date -d "May 29 1953" +%s)
4519         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4520
4521         touch -m -d @$far_past_mtime $DIR1/$tfile
4522         touch -a -d @$far_past_atime $DIR1/$tfile
4523
4524         for (( i=0; i < 2; i++ )) ; do
4525                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4526                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4527                         error "atime or mtime set incorrectly"
4528
4529                 cancel_lru_locks $OSC
4530                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4531         done
4532 }
4533 run_test 39m "test atime and mtime before 1970"
4534
4535 test_39n() { # LU-3832
4536         remote_mds_nodsh && skip "remote MDS with nodsh"
4537
4538         local atime_diff=$(do_facet $SINGLEMDS \
4539                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4540         local atime0
4541         local atime1
4542         local atime2
4543
4544         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4545
4546         rm -rf $DIR/$tfile
4547         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4548         atime0=$(stat -c %X $DIR/$tfile)
4549
4550         sleep 5
4551         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4552         atime1=$(stat -c %X $DIR/$tfile)
4553
4554         sleep 5
4555         cancel_lru_locks mdc
4556         cancel_lru_locks osc
4557         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4558         atime2=$(stat -c %X $DIR/$tfile)
4559
4560         do_facet $SINGLEMDS \
4561                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4562
4563         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4564         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4565 }
4566 run_test 39n "check that O_NOATIME is honored"
4567
4568 test_39o() {
4569         TESTDIR=$DIR/$tdir/$tfile
4570         [ -e $TESTDIR ] && rm -rf $TESTDIR
4571         mkdir -p $TESTDIR
4572         cd $TESTDIR
4573         links1=2
4574         ls
4575         mkdir a b
4576         ls
4577         links2=$(stat -c %h .)
4578         [ $(($links1 + 2)) != $links2 ] &&
4579                 error "wrong links count $(($links1 + 2)) != $links2"
4580         rmdir b
4581         links3=$(stat -c %h .)
4582         [ $(($links1 + 1)) != $links3 ] &&
4583                 error "wrong links count $links1 != $links3"
4584         return 0
4585 }
4586 run_test 39o "directory cached attributes updated after create"
4587
4588 test_39p() {
4589         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4590
4591         local MDTIDX=1
4592         TESTDIR=$DIR/$tdir/$tdir
4593         [ -e $TESTDIR ] && rm -rf $TESTDIR
4594         test_mkdir -p $TESTDIR
4595         cd $TESTDIR
4596         links1=2
4597         ls
4598         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4599         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4600         ls
4601         links2=$(stat -c %h .)
4602         [ $(($links1 + 2)) != $links2 ] &&
4603                 error "wrong links count $(($links1 + 2)) != $links2"
4604         rmdir remote_dir2
4605         links3=$(stat -c %h .)
4606         [ $(($links1 + 1)) != $links3 ] &&
4607                 error "wrong links count $links1 != $links3"
4608         return 0
4609 }
4610 run_test 39p "remote directory cached attributes updated after create ========"
4611
4612 test_39r() {
4613         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4614                 skip "no atime update on old OST"
4615         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4616                 skip_env "ldiskfs only test"
4617         fi
4618
4619         local saved_adiff
4620         saved_adiff=$(do_facet ost1 \
4621                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4622         stack_trap "do_facet ost1 \
4623                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4624
4625         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4626
4627         $LFS setstripe -i 0 $DIR/$tfile
4628         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4629                 error "can't write initial file"
4630         cancel_lru_locks osc
4631
4632         # exceed atime_diff and access file
4633         sleep 6
4634         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4635
4636         local atime_cli=$(stat -c %X $DIR/$tfile)
4637         echo "client atime: $atime_cli"
4638         # allow atime update to be written to device
4639         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4640         sleep 5
4641
4642         local ostdev=$(ostdevname 1)
4643         local fid=($(lfs getstripe -y $DIR/$tfile |
4644                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4645         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4646         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4647
4648         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4649         local atime_ost=$(do_facet ost1 "$cmd" |&
4650                           awk -F'[: ]' '/atime:/ { print $4 }')
4651         (( atime_cli == atime_ost )) ||
4652                 error "atime on client $atime_cli != ost $atime_ost"
4653 }
4654 run_test 39r "lazy atime update on OST"
4655
4656 test_39q() { # LU-8041
4657         local testdir=$DIR/$tdir
4658         mkdir -p $testdir
4659         multiop_bg_pause $testdir D_c || error "multiop failed"
4660         local multipid=$!
4661         cancel_lru_locks mdc
4662         kill -USR1 $multipid
4663         local atime=$(stat -c %X $testdir)
4664         [ "$atime" -ne 0 ] || error "atime is zero"
4665 }
4666 run_test 39q "close won't zero out atime"
4667
4668 test_40() {
4669         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4670         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4671                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4672         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4673                 error "$tfile is not 4096 bytes in size"
4674 }
4675 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4676
4677 test_41() {
4678         # bug 1553
4679         small_write $DIR/f41 18
4680 }
4681 run_test 41 "test small file write + fstat ====================="
4682
4683 count_ost_writes() {
4684         lctl get_param -n ${OSC}.*.stats |
4685                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4686                         END { printf("%0.0f", writes) }'
4687 }
4688
4689 # decent default
4690 WRITEBACK_SAVE=500
4691 DIRTY_RATIO_SAVE=40
4692 MAX_DIRTY_RATIO=50
4693 BG_DIRTY_RATIO_SAVE=10
4694 MAX_BG_DIRTY_RATIO=25
4695
4696 start_writeback() {
4697         trap 0
4698         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4699         # dirty_ratio, dirty_background_ratio
4700         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4701                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4702                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4703                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4704         else
4705                 # if file not here, we are a 2.4 kernel
4706                 kill -CONT `pidof kupdated`
4707         fi
4708 }
4709
4710 stop_writeback() {
4711         # setup the trap first, so someone cannot exit the test at the
4712         # exact wrong time and mess up a machine
4713         trap start_writeback EXIT
4714         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4715         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4716                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4717                 sysctl -w vm.dirty_writeback_centisecs=0
4718                 sysctl -w vm.dirty_writeback_centisecs=0
4719                 # save and increase /proc/sys/vm/dirty_ratio
4720                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4721                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4722                 # save and increase /proc/sys/vm/dirty_background_ratio
4723                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4724                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4725         else
4726                 # if file not here, we are a 2.4 kernel
4727                 kill -STOP `pidof kupdated`
4728         fi
4729 }
4730
4731 # ensure that all stripes have some grant before we test client-side cache
4732 setup_test42() {
4733         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4734                 dd if=/dev/zero of=$i bs=4k count=1
4735                 rm $i
4736         done
4737 }
4738
4739 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4740 # file truncation, and file removal.
4741 test_42a() {
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743
4744         setup_test42
4745         cancel_lru_locks $OSC
4746         stop_writeback
4747         sync; sleep 1; sync # just to be safe
4748         BEFOREWRITES=`count_ost_writes`
4749         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4750         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4751         AFTERWRITES=`count_ost_writes`
4752         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4753                 error "$BEFOREWRITES < $AFTERWRITES"
4754         start_writeback
4755 }
4756 run_test 42a "ensure that we don't flush on close"
4757
4758 test_42b() {
4759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4760
4761         setup_test42
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         sync
4765         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4766         BEFOREWRITES=$(count_ost_writes)
4767         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4768         AFTERWRITES=$(count_ost_writes)
4769         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4770                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4771         fi
4772         BEFOREWRITES=$(count_ost_writes)
4773         sync || error "sync: $?"
4774         AFTERWRITES=$(count_ost_writes)
4775         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4776                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4777         fi
4778         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4779         start_writeback
4780         return 0
4781 }
4782 run_test 42b "test destroy of file with cached dirty data ======"
4783
4784 # if these tests just want to test the effect of truncation,
4785 # they have to be very careful.  consider:
4786 # - the first open gets a {0,EOF}PR lock
4787 # - the first write conflicts and gets a {0, count-1}PW
4788 # - the rest of the writes are under {count,EOF}PW
4789 # - the open for truncate tries to match a {0,EOF}PR
4790 #   for the filesize and cancels the PWs.
4791 # any number of fixes (don't get {0,EOF} on open, match
4792 # composite locks, do smarter file size management) fix
4793 # this, but for now we want these tests to verify that
4794 # the cancellation with truncate intent works, so we
4795 # start the file with a full-file pw lock to match against
4796 # until the truncate.
4797 trunc_test() {
4798         test=$1
4799         file=$DIR/$test
4800         offset=$2
4801         cancel_lru_locks $OSC
4802         stop_writeback
4803         # prime the file with 0,EOF PW to match
4804         touch $file
4805         $TRUNCATE $file 0
4806         sync; sync
4807         # now the real test..
4808         dd if=/dev/zero of=$file bs=1024 count=100
4809         BEFOREWRITES=`count_ost_writes`
4810         $TRUNCATE $file $offset
4811         cancel_lru_locks $OSC
4812         AFTERWRITES=`count_ost_writes`
4813         start_writeback
4814 }
4815
4816 test_42c() {
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         trunc_test 42c 1024
4820         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4821                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4822         rm $file
4823 }
4824 run_test 42c "test partial truncate of file with cached dirty data"
4825
4826 test_42d() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         trunc_test 42d 0
4830         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4831                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4832         rm $file
4833 }
4834 run_test 42d "test complete truncate of file with cached dirty data"
4835
4836 test_42e() { # bug22074
4837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4838
4839         local TDIR=$DIR/${tdir}e
4840         local pages=16 # hardcoded 16 pages, don't change it.
4841         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4842         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4843         local max_dirty_mb
4844         local warmup_files
4845
4846         test_mkdir $DIR/${tdir}e
4847         $LFS setstripe -c 1 $TDIR
4848         createmany -o $TDIR/f $files
4849
4850         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4851
4852         # we assume that with $OSTCOUNT files, at least one of them will
4853         # be allocated on OST0.
4854         warmup_files=$((OSTCOUNT * max_dirty_mb))
4855         createmany -o $TDIR/w $warmup_files
4856
4857         # write a large amount of data into one file and sync, to get good
4858         # avail_grant number from OST.
4859         for ((i=0; i<$warmup_files; i++)); do
4860                 idx=$($LFS getstripe -i $TDIR/w$i)
4861                 [ $idx -ne 0 ] && continue
4862                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4863                 break
4864         done
4865         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4866         sync
4867         $LCTL get_param $proc_osc0/cur_dirty_bytes
4868         $LCTL get_param $proc_osc0/cur_grant_bytes
4869
4870         # create as much dirty pages as we can while not to trigger the actual
4871         # RPCs directly. but depends on the env, VFS may trigger flush during this
4872         # period, hopefully we are good.
4873         for ((i=0; i<$warmup_files; i++)); do
4874                 idx=$($LFS getstripe -i $TDIR/w$i)
4875                 [ $idx -ne 0 ] && continue
4876                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4877         done
4878         $LCTL get_param $proc_osc0/cur_dirty_bytes
4879         $LCTL get_param $proc_osc0/cur_grant_bytes
4880
4881         # perform the real test
4882         $LCTL set_param $proc_osc0/rpc_stats 0
4883         for ((;i<$files; i++)); do
4884                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4885                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4886         done
4887         sync
4888         $LCTL get_param $proc_osc0/rpc_stats
4889
4890         local percent=0
4891         local have_ppr=false
4892         $LCTL get_param $proc_osc0/rpc_stats |
4893                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4894                         # skip lines until we are at the RPC histogram data
4895                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4896                         $have_ppr || continue
4897
4898                         # we only want the percent stat for < 16 pages
4899                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4900
4901                         percent=$((percent + WPCT))
4902                         if [[ $percent -gt 15 ]]; then
4903                                 error "less than 16-pages write RPCs" \
4904                                       "$percent% > 15%"
4905                                 break
4906                         fi
4907                 done
4908         rm -rf $TDIR
4909 }
4910 run_test 42e "verify sub-RPC writes are not done synchronously"
4911
4912 test_43A() { # was test_43
4913         test_mkdir $DIR/$tdir
4914         cp -p /bin/ls $DIR/$tdir/$tfile
4915         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4916         pid=$!
4917         # give multiop a chance to open
4918         sleep 1
4919
4920         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4921         kill -USR1 $pid
4922         # Wait for multiop to exit
4923         wait $pid
4924 }
4925 run_test 43A "execution of file opened for write should return -ETXTBSY"
4926
4927 test_43a() {
4928         test_mkdir $DIR/$tdir
4929         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4930         $DIR/$tdir/sleep 60 &
4931         SLEEP_PID=$!
4932         # Make sure exec of $tdir/sleep wins race with truncate
4933         sleep 1
4934         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4935         kill $SLEEP_PID
4936 }
4937 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4938
4939 test_43b() {
4940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4941
4942         test_mkdir $DIR/$tdir
4943         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4944         $DIR/$tdir/sleep 60 &
4945         SLEEP_PID=$!
4946         # Make sure exec of $tdir/sleep wins race with truncate
4947         sleep 1
4948         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4949         kill $SLEEP_PID
4950 }
4951 run_test 43b "truncate of file being executed should return -ETXTBSY"
4952
4953 test_43c() {
4954         local testdir="$DIR/$tdir"
4955         test_mkdir $testdir
4956         cp $SHELL $testdir/
4957         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4958                 ( cd $testdir && md5sum -c )
4959 }
4960 run_test 43c "md5sum of copy into lustre"
4961
4962 test_44A() { # was test_44
4963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4964
4965         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4966         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4967 }
4968 run_test 44A "zero length read from a sparse stripe"
4969
4970 test_44a() {
4971         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4972                 awk '{ print $2 }')
4973         [ -z "$nstripe" ] && skip "can't get stripe info"
4974         [[ $nstripe -gt $OSTCOUNT ]] &&
4975                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4976
4977         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4978                 awk '{ print $2 }')
4979         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4980                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4981                         awk '{ print $2 }')
4982         fi
4983
4984         OFFSETS="0 $((stride/2)) $((stride-1))"
4985         for offset in $OFFSETS; do
4986                 for i in $(seq 0 $((nstripe-1))); do
4987                         local GLOBALOFFSETS=""
4988                         # size in Bytes
4989                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4990                         local myfn=$DIR/d44a-$size
4991                         echo "--------writing $myfn at $size"
4992                         ll_sparseness_write $myfn $size ||
4993                                 error "ll_sparseness_write"
4994                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4995                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4996                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4997
4998                         for j in $(seq 0 $((nstripe-1))); do
4999                                 # size in Bytes
5000                                 size=$((((j + $nstripe )*$stride + $offset)))
5001                                 ll_sparseness_write $myfn $size ||
5002                                         error "ll_sparseness_write"
5003                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5004                         done
5005                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5006                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5007                         rm -f $myfn
5008                 done
5009         done
5010 }
5011 run_test 44a "test sparse pwrite ==============================="
5012
5013 dirty_osc_total() {
5014         tot=0
5015         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5016                 tot=$(($tot + $d))
5017         done
5018         echo $tot
5019 }
5020 do_dirty_record() {
5021         before=`dirty_osc_total`
5022         echo executing "\"$*\""
5023         eval $*
5024         after=`dirty_osc_total`
5025         echo before $before, after $after
5026 }
5027 test_45() {
5028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5029
5030         f="$DIR/f45"
5031         # Obtain grants from OST if it supports it
5032         echo blah > ${f}_grant
5033         stop_writeback
5034         sync
5035         do_dirty_record "echo blah > $f"
5036         [[ $before -eq $after ]] && error "write wasn't cached"
5037         do_dirty_record "> $f"
5038         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5039         do_dirty_record "echo blah > $f"
5040         [[ $before -eq $after ]] && error "write wasn't cached"
5041         do_dirty_record "sync"
5042         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5043         do_dirty_record "echo blah > $f"
5044         [[ $before -eq $after ]] && error "write wasn't cached"
5045         do_dirty_record "cancel_lru_locks osc"
5046         [[ $before -gt $after ]] ||
5047                 error "lock cancellation didn't lower dirty count"
5048         start_writeback
5049 }
5050 run_test 45 "osc io page accounting ============================"
5051
5052 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5053 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5054 # objects offset and an assert hit when an rpc was built with 1023's mapped
5055 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5056 test_46() {
5057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5058
5059         f="$DIR/f46"
5060         stop_writeback
5061         sync
5062         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5063         sync
5064         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5065         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5066         sync
5067         start_writeback
5068 }
5069 run_test 46 "dirtying a previously written page ================"
5070
5071 # test_47 is removed "Device nodes check" is moved to test_28
5072
5073 test_48a() { # bug 2399
5074         [ "$mds1_FSTYPE" = "zfs" ] &&
5075         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5076                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5077
5078         test_mkdir $DIR/$tdir
5079         cd $DIR/$tdir
5080         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5081         test_mkdir $DIR/$tdir
5082         touch foo || error "'touch foo' failed after recreating cwd"
5083         test_mkdir bar
5084         touch .foo || error "'touch .foo' failed after recreating cwd"
5085         test_mkdir .bar
5086         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5087         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5088         cd . || error "'cd .' failed after recreating cwd"
5089         mkdir . && error "'mkdir .' worked after recreating cwd"
5090         rmdir . && error "'rmdir .' worked after recreating cwd"
5091         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5092         cd .. || error "'cd ..' failed after recreating cwd"
5093 }
5094 run_test 48a "Access renamed working dir (should return errors)="
5095
5096 test_48b() { # bug 2399
5097         rm -rf $DIR/$tdir
5098         test_mkdir $DIR/$tdir
5099         cd $DIR/$tdir
5100         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5101         touch foo && error "'touch foo' worked after removing cwd"
5102         mkdir foo && error "'mkdir foo' worked after removing cwd"
5103         touch .foo && error "'touch .foo' worked after removing cwd"
5104         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5105         ls . > /dev/null && error "'ls .' worked after removing cwd"
5106         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5107         mkdir . && error "'mkdir .' worked after removing cwd"
5108         rmdir . && error "'rmdir .' worked after removing cwd"
5109         ln -s . foo && error "'ln -s .' worked after removing cwd"
5110         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5111 }
5112 run_test 48b "Access removed working dir (should return errors)="
5113
5114 test_48c() { # bug 2350
5115         #lctl set_param debug=-1
5116         #set -vx
5117         rm -rf $DIR/$tdir
5118         test_mkdir -p $DIR/$tdir/dir
5119         cd $DIR/$tdir/dir
5120         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5121         $TRACE touch foo && error "touch foo worked after removing cwd"
5122         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5123         touch .foo && error "touch .foo worked after removing cwd"
5124         mkdir .foo && error "mkdir .foo worked after removing cwd"
5125         $TRACE ls . && error "'ls .' worked after removing cwd"
5126         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5127         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5128         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5129         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5130         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5131 }
5132 run_test 48c "Access removed working subdir (should return errors)"
5133
5134 test_48d() { # bug 2350
5135         #lctl set_param debug=-1
5136         #set -vx
5137         rm -rf $DIR/$tdir
5138         test_mkdir -p $DIR/$tdir/dir
5139         cd $DIR/$tdir/dir
5140         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5141         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5142         $TRACE touch foo && error "'touch foo' worked after removing parent"
5143         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5144         touch .foo && error "'touch .foo' worked after removing parent"
5145         mkdir .foo && error "mkdir .foo worked after removing parent"
5146         $TRACE ls . && error "'ls .' worked after removing parent"
5147         $TRACE ls .. && error "'ls ..' worked after removing parent"
5148         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5149         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5150         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5151         true
5152 }
5153 run_test 48d "Access removed parent subdir (should return errors)"
5154
5155 test_48e() { # bug 4134
5156         #lctl set_param debug=-1
5157         #set -vx
5158         rm -rf $DIR/$tdir
5159         test_mkdir -p $DIR/$tdir/dir
5160         cd $DIR/$tdir/dir
5161         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5162         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5163         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5164         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5165         # On a buggy kernel addition of "touch foo" after cd .. will
5166         # produce kernel oops in lookup_hash_it
5167         touch ../foo && error "'cd ..' worked after recreate parent"
5168         cd $DIR
5169         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5170 }
5171 run_test 48e "Access to recreated parent subdir (should return errors)"
5172
5173 test_48f() {
5174         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5175                 skip "need MDS >= 2.13.55"
5176         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5177         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5178                 skip "needs different host for mdt1 mdt2"
5179         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5180
5181         $LFS mkdir -i0 $DIR/$tdir
5182         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5183
5184         for d in sub1 sub2 sub3; do
5185                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5186                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5187                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5188         done
5189
5190         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5191 }
5192 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5193
5194 test_49() { # LU-1030
5195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5196         remote_ost_nodsh && skip "remote OST with nodsh"
5197
5198         # get ost1 size - $FSNAME-OST0000
5199         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5200                 awk '{ print $4 }')
5201         # write 800M at maximum
5202         [[ $ost1_size -lt 2 ]] && ost1_size=2
5203         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5204
5205         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5206         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5207         local dd_pid=$!
5208
5209         # change max_pages_per_rpc while writing the file
5210         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5211         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5212         # loop until dd process exits
5213         while ps ax -opid | grep -wq $dd_pid; do
5214                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5215                 sleep $((RANDOM % 5 + 1))
5216         done
5217         # restore original max_pages_per_rpc
5218         $LCTL set_param $osc1_mppc=$orig_mppc
5219         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5220 }
5221 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5222
5223 test_50() {
5224         # bug 1485
5225         test_mkdir $DIR/$tdir
5226         cd $DIR/$tdir
5227         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5228 }
5229 run_test 50 "special situations: /proc symlinks  ==============="
5230
5231 test_51a() {    # was test_51
5232         # bug 1516 - create an empty entry right after ".." then split dir
5233         test_mkdir -c1 $DIR/$tdir
5234         touch $DIR/$tdir/foo
5235         $MCREATE $DIR/$tdir/bar
5236         rm $DIR/$tdir/foo
5237         createmany -m $DIR/$tdir/longfile 201
5238         FNUM=202
5239         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5240                 $MCREATE $DIR/$tdir/longfile$FNUM
5241                 FNUM=$(($FNUM + 1))
5242                 echo -n "+"
5243         done
5244         echo
5245         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5246 }
5247 run_test 51a "special situations: split htree with empty entry =="
5248
5249 cleanup_print_lfs_df () {
5250         trap 0
5251         $LFS df
5252         $LFS df -i
5253 }
5254
5255 test_51b() {
5256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5257
5258         local dir=$DIR/$tdir
5259         local nrdirs=$((65536 + 100))
5260
5261         # cleanup the directory
5262         rm -fr $dir
5263
5264         test_mkdir -c1 $dir
5265
5266         $LFS df
5267         $LFS df -i
5268         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5269         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5270         [[ $numfree -lt $nrdirs ]] &&
5271                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5272
5273         # need to check free space for the directories as well
5274         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5275         numfree=$(( blkfree / $(fs_inode_ksize) ))
5276         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5277
5278         trap cleanup_print_lfs_df EXIT
5279
5280         # create files
5281         createmany -d $dir/d $nrdirs || {
5282                 unlinkmany $dir/d $nrdirs
5283                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5284         }
5285
5286         # really created :
5287         nrdirs=$(ls -U $dir | wc -l)
5288
5289         # unlink all but 100 subdirectories, then check it still works
5290         local left=100
5291         local delete=$((nrdirs - left))
5292
5293         $LFS df
5294         $LFS df -i
5295
5296         # for ldiskfs the nlink count should be 1, but this is OSD specific
5297         # and so this is listed for informational purposes only
5298         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5299         unlinkmany -d $dir/d $delete ||
5300                 error "unlink of first $delete subdirs failed"
5301
5302         echo "nlink between: $(stat -c %h $dir)"
5303         local found=$(ls -U $dir | wc -l)
5304         [ $found -ne $left ] &&
5305                 error "can't find subdirs: found only $found, expected $left"
5306
5307         unlinkmany -d $dir/d $delete $left ||
5308                 error "unlink of second $left subdirs failed"
5309         # regardless of whether the backing filesystem tracks nlink accurately
5310         # or not, the nlink count shouldn't be more than "." and ".." here
5311         local after=$(stat -c %h $dir)
5312         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5313                 echo "nlink after: $after"
5314
5315         cleanup_print_lfs_df
5316 }
5317 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5318
5319 test_51d() {
5320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5321         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5322
5323         test_mkdir $DIR/$tdir
5324         createmany -o $DIR/$tdir/t- 1000
5325         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5326         for N in $(seq 0 $((OSTCOUNT - 1))); do
5327                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5328                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5329                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5330                         '($1 == '$N') { objs += 1 } \
5331                         END { printf("%0.0f", objs) }')
5332                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5333         done
5334         unlinkmany $DIR/$tdir/t- 1000
5335
5336         NLAST=0
5337         for N in $(seq 1 $((OSTCOUNT - 1))); do
5338                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5339                         error "OST $N has less objects vs OST $NLAST" \
5340                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5341                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5342                         error "OST $N has less objects vs OST $NLAST" \
5343                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5344
5345                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5346                         error "OST $N has less #0 objects vs OST $NLAST" \
5347                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5348                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5349                         error "OST $N has less #0 objects vs OST $NLAST" \
5350                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5351                 NLAST=$N
5352         done
5353         rm -f $TMP/$tfile
5354 }
5355 run_test 51d "check object distribution"
5356
5357 test_51e() {
5358         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5359                 skip_env "ldiskfs only test"
5360         fi
5361
5362         test_mkdir -c1 $DIR/$tdir
5363         test_mkdir -c1 $DIR/$tdir/d0
5364
5365         touch $DIR/$tdir/d0/foo
5366         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5367                 error "file exceed 65000 nlink limit!"
5368         unlinkmany $DIR/$tdir/d0/f- 65001
5369         return 0
5370 }
5371 run_test 51e "check file nlink limit"
5372
5373 test_51f() {
5374         test_mkdir $DIR/$tdir
5375
5376         local max=100000
5377         local ulimit_old=$(ulimit -n)
5378         local spare=20 # number of spare fd's for scripts/libraries, etc.
5379         local mdt=$($LFS getstripe -m $DIR/$tdir)
5380         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5381
5382         echo "MDT$mdt numfree=$numfree, max=$max"
5383         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5384         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5385                 while ! ulimit -n $((numfree + spare)); do
5386                         numfree=$((numfree * 3 / 4))
5387                 done
5388                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5389         else
5390                 echo "left ulimit at $ulimit_old"
5391         fi
5392
5393         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5394                 unlinkmany $DIR/$tdir/f $numfree
5395                 error "create+open $numfree files in $DIR/$tdir failed"
5396         }
5397         ulimit -n $ulimit_old
5398
5399         # if createmany exits at 120s there will be fewer than $numfree files
5400         unlinkmany $DIR/$tdir/f $numfree || true
5401 }
5402 run_test 51f "check many open files limit"
5403
5404 test_52a() {
5405         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5406         test_mkdir $DIR/$tdir
5407         touch $DIR/$tdir/foo
5408         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5409         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5410         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5411         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5412         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5413                                         error "link worked"
5414         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5415         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5416         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5417                                                      error "lsattr"
5418         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5419         cp -r $DIR/$tdir $TMP/
5420         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5421 }
5422 run_test 52a "append-only flag test (should return errors)"
5423
5424 test_52b() {
5425         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5426         test_mkdir $DIR/$tdir
5427         touch $DIR/$tdir/foo
5428         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5429         cat test > $DIR/$tdir/foo && error "cat test worked"
5430         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5431         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5432         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5433                                         error "link worked"
5434         echo foo >> $DIR/$tdir/foo && error "echo worked"
5435         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5436         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5437         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5438         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5439                                                         error "lsattr"
5440         chattr -i $DIR/$tdir/foo || error "chattr failed"
5441
5442         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5443 }
5444 run_test 52b "immutable flag test (should return errors) ======="
5445
5446 test_53() {
5447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5448         remote_mds_nodsh && skip "remote MDS with nodsh"
5449         remote_ost_nodsh && skip "remote OST with nodsh"
5450
5451         local param
5452         local param_seq
5453         local ostname
5454         local mds_last
5455         local mds_last_seq
5456         local ost_last
5457         local ost_last_seq
5458         local ost_last_id
5459         local ostnum
5460         local node
5461         local found=false
5462         local support_last_seq=true
5463
5464         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5465                 support_last_seq=false
5466
5467         # only test MDT0000
5468         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5469         local value
5470         for value in $(do_facet $SINGLEMDS \
5471                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5472                 param=$(echo ${value[0]} | cut -d "=" -f1)
5473                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5474
5475                 if $support_last_seq; then
5476                         param_seq=$(echo $param |
5477                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5478                         mds_last_seq=$(do_facet $SINGLEMDS \
5479                                        $LCTL get_param -n $param_seq)
5480                 fi
5481                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5482
5483                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5484                 node=$(facet_active_host ost$((ostnum+1)))
5485                 param="obdfilter.$ostname.last_id"
5486                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5487                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5488                         ost_last_id=$ost_last
5489
5490                         if $support_last_seq; then
5491                                 ost_last_id=$(echo $ost_last |
5492                                               awk -F':' '{print $2}' |
5493                                               sed -e "s/^0x//g")
5494                                 ost_last_seq=$(echo $ost_last |
5495                                                awk -F':' '{print $1}')
5496                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5497                         fi
5498
5499                         if [[ $ost_last_id != $mds_last ]]; then
5500                                 error "$ost_last_id != $mds_last"
5501                         else
5502                                 found=true
5503                                 break
5504                         fi
5505                 done
5506         done
5507         $found || error "can not match last_seq/last_id for $mdtosc"
5508         return 0
5509 }
5510 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5511
5512 test_54a() {
5513         perl -MSocket -e ';' || skip "no Socket perl module installed"
5514
5515         $SOCKETSERVER $DIR/socket ||
5516                 error "$SOCKETSERVER $DIR/socket failed: $?"
5517         $SOCKETCLIENT $DIR/socket ||
5518                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5519         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5520 }
5521 run_test 54a "unix domain socket test =========================="
5522
5523 test_54b() {
5524         f="$DIR/f54b"
5525         mknod $f c 1 3
5526         chmod 0666 $f
5527         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5528 }
5529 run_test 54b "char device works in lustre ======================"
5530
5531 find_loop_dev() {
5532         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5533         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5534         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5535
5536         for i in $(seq 3 7); do
5537                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5538                 LOOPDEV=$LOOPBASE$i
5539                 LOOPNUM=$i
5540                 break
5541         done
5542 }
5543
5544 cleanup_54c() {
5545         local rc=0
5546         loopdev="$DIR/loop54c"
5547
5548         trap 0
5549         $UMOUNT $DIR/$tdir || rc=$?
5550         losetup -d $loopdev || true
5551         losetup -d $LOOPDEV || true
5552         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5553         return $rc
5554 }
5555
5556 test_54c() {
5557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5558
5559         loopdev="$DIR/loop54c"
5560
5561         find_loop_dev
5562         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5563         trap cleanup_54c EXIT
5564         mknod $loopdev b 7 $LOOPNUM
5565         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5566         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5567         losetup $loopdev $DIR/$tfile ||
5568                 error "can't set up $loopdev for $DIR/$tfile"
5569         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5570         test_mkdir $DIR/$tdir
5571         mount -t ext2 $loopdev $DIR/$tdir ||
5572                 error "error mounting $loopdev on $DIR/$tdir"
5573         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5574                 error "dd write"
5575         df $DIR/$tdir
5576         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5577                 error "dd read"
5578         cleanup_54c
5579 }
5580 run_test 54c "block device works in lustre ====================="
5581
5582 test_54d() {
5583         f="$DIR/f54d"
5584         string="aaaaaa"
5585         mknod $f p
5586         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5587 }
5588 run_test 54d "fifo device works in lustre ======================"
5589
5590 test_54e() {
5591         f="$DIR/f54e"
5592         string="aaaaaa"
5593         cp -aL /dev/console $f
5594         echo $string > $f || error "echo $string to $f failed"
5595 }
5596 run_test 54e "console/tty device works in lustre ======================"
5597
5598 test_56a() {
5599         local numfiles=3
5600         local dir=$DIR/$tdir
5601
5602         rm -rf $dir
5603         test_mkdir -p $dir/dir
5604         for i in $(seq $numfiles); do
5605                 touch $dir/file$i
5606                 touch $dir/dir/file$i
5607         done
5608
5609         local numcomp=$($LFS getstripe --component-count $dir)
5610
5611         [[ $numcomp == 0 ]] && numcomp=1
5612
5613         # test lfs getstripe with --recursive
5614         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5615
5616         [[ $filenum -eq $((numfiles * 2)) ]] ||
5617                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5618         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5619         [[ $filenum -eq $numfiles ]] ||
5620                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5621         echo "$LFS getstripe showed obdidx or l_ost_idx"
5622
5623         # test lfs getstripe with file instead of dir
5624         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5625         [[ $filenum -eq 1 ]] ||
5626                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5627         echo "$LFS getstripe file1 passed"
5628
5629         #test lfs getstripe with --verbose
5630         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5631         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5632                 error "$LFS getstripe --verbose $dir: "\
5633                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5634         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5635                 error "$LFS getstripe $dir: showed lmm_magic"
5636
5637         #test lfs getstripe with -v prints lmm_fid
5638         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5639         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5640                 error "$LFS getstripe -v $dir: "\
5641                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5642         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5643                 error "$LFS getstripe $dir: showed lmm_fid by default"
5644         echo "$LFS getstripe --verbose passed"
5645
5646         #check for FID information
5647         local fid1=$($LFS getstripe --fid $dir/file1)
5648         local fid2=$($LFS getstripe --verbose $dir/file1 |
5649                      awk '/lmm_fid: / { print $2; exit; }')
5650         local fid3=$($LFS path2fid $dir/file1)
5651
5652         [ "$fid1" != "$fid2" ] &&
5653                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5654         [ "$fid1" != "$fid3" ] &&
5655                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5656         echo "$LFS getstripe --fid passed"
5657
5658         #test lfs getstripe with --obd
5659         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5660                 error "$LFS getstripe --obd wrong_uuid: should return error"
5661
5662         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5663
5664         local ostidx=1
5665         local obduuid=$(ostuuid_from_index $ostidx)
5666         local found=$($LFS getstripe -r --obd $obduuid $dir |
5667                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5668
5669         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5670         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5671                 ((filenum--))
5672         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5673                 ((filenum--))
5674
5675         [[ $found -eq $filenum ]] ||
5676                 error "$LFS getstripe --obd: found $found expect $filenum"
5677         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5678                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5679                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5680                 error "$LFS getstripe --obd: should not show file on other obd"
5681         echo "$LFS getstripe --obd passed"
5682 }
5683 run_test 56a "check $LFS getstripe"
5684
5685 test_56b() {
5686         local dir=$DIR/$tdir
5687         local numdirs=3
5688
5689         test_mkdir $dir
5690         for i in $(seq $numdirs); do
5691                 test_mkdir $dir/dir$i
5692         done
5693
5694         # test lfs getdirstripe default mode is non-recursion, which is
5695         # different from lfs getstripe
5696         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5697
5698         [[ $dircnt -eq 1 ]] ||
5699                 error "$LFS getdirstripe: found $dircnt, not 1"
5700         dircnt=$($LFS getdirstripe --recursive $dir |
5701                 grep -c lmv_stripe_count)
5702         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5703                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5704 }
5705 run_test 56b "check $LFS getdirstripe"
5706
5707 test_56c() {
5708         remote_ost_nodsh && skip "remote OST with nodsh"
5709
5710         local ost_idx=0
5711         local ost_name=$(ostname_from_index $ost_idx)
5712         local old_status=$(ost_dev_status $ost_idx)
5713         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5714
5715         [[ -z "$old_status" ]] ||
5716                 skip_env "OST $ost_name is in $old_status status"
5717
5718         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5719         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5720                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5721         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5722                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5723                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5724         fi
5725
5726         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5727                 error "$LFS df -v showing inactive devices"
5728         sleep_maxage
5729
5730         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5731
5732         [[ "$new_status" =~ "D" ]] ||
5733                 error "$ost_name status is '$new_status', missing 'D'"
5734         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5735                 [[ "$new_status" =~ "N" ]] ||
5736                         error "$ost_name status is '$new_status', missing 'N'"
5737         fi
5738         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5739                 [[ "$new_status" =~ "f" ]] ||
5740                         error "$ost_name status is '$new_status', missing 'f'"
5741         fi
5742
5743         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5744         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5745                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5746         [[ -z "$p" ]] && restore_lustre_params < $p || true
5747         sleep_maxage
5748
5749         new_status=$(ost_dev_status $ost_idx)
5750         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5751                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5752         # can't check 'f' as devices may actually be on flash
5753 }
5754 run_test 56c "check 'lfs df' showing device status"
5755
5756 test_56d() {
5757         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5758         local osts=$($LFS df -v $MOUNT | grep -c OST)
5759
5760         $LFS df $MOUNT
5761
5762         (( mdts == MDSCOUNT )) ||
5763                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5764         (( osts == OSTCOUNT )) ||
5765                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5766 }
5767 run_test 56d "'lfs df -v' prints only configured devices"
5768
5769 NUMFILES=3
5770 NUMDIRS=3
5771 setup_56() {
5772         local local_tdir="$1"
5773         local local_numfiles="$2"
5774         local local_numdirs="$3"
5775         local dir_params="$4"
5776         local dir_stripe_params="$5"
5777
5778         if [ ! -d "$local_tdir" ] ; then
5779                 test_mkdir -p $dir_stripe_params $local_tdir
5780                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5781                 for i in $(seq $local_numfiles) ; do
5782                         touch $local_tdir/file$i
5783                 done
5784                 for i in $(seq $local_numdirs) ; do
5785                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5786                         for j in $(seq $local_numfiles) ; do
5787                                 touch $local_tdir/dir$i/file$j
5788                         done
5789                 done
5790         fi
5791 }
5792
5793 setup_56_special() {
5794         local local_tdir=$1
5795         local local_numfiles=$2
5796         local local_numdirs=$3
5797
5798         setup_56 $local_tdir $local_numfiles $local_numdirs
5799
5800         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5801                 for i in $(seq $local_numfiles) ; do
5802                         mknod $local_tdir/loop${i}b b 7 $i
5803                         mknod $local_tdir/null${i}c c 1 3
5804                         ln -s $local_tdir/file1 $local_tdir/link${i}
5805                 done
5806                 for i in $(seq $local_numdirs) ; do
5807                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5808                         mknod $local_tdir/dir$i/null${i}c c 1 3
5809                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5810                 done
5811         fi
5812 }
5813
5814 test_56g() {
5815         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5816         local expected=$(($NUMDIRS + 2))
5817
5818         setup_56 $dir $NUMFILES $NUMDIRS
5819
5820         # test lfs find with -name
5821         for i in $(seq $NUMFILES) ; do
5822                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5823
5824                 [ $nums -eq $expected ] ||
5825                         error "lfs find -name '*$i' $dir wrong: "\
5826                               "found $nums, expected $expected"
5827         done
5828 }
5829 run_test 56g "check lfs find -name"
5830
5831 test_56h() {
5832         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5833         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5834
5835         setup_56 $dir $NUMFILES $NUMDIRS
5836
5837         # test lfs find with ! -name
5838         for i in $(seq $NUMFILES) ; do
5839                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5840
5841                 [ $nums -eq $expected ] ||
5842                         error "lfs find ! -name '*$i' $dir wrong: "\
5843                               "found $nums, expected $expected"
5844         done
5845 }
5846 run_test 56h "check lfs find ! -name"
5847
5848 test_56i() {
5849         local dir=$DIR/$tdir
5850
5851         test_mkdir $dir
5852
5853         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5854         local out=$($cmd)
5855
5856         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5857 }
5858 run_test 56i "check 'lfs find -ost UUID' skips directories"
5859
5860 test_56j() {
5861         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5862
5863         setup_56_special $dir $NUMFILES $NUMDIRS
5864
5865         local expected=$((NUMDIRS + 1))
5866         local cmd="$LFS find -type d $dir"
5867         local nums=$($cmd | wc -l)
5868
5869         [ $nums -eq $expected ] ||
5870                 error "'$cmd' wrong: found $nums, expected $expected"
5871 }
5872 run_test 56j "check lfs find -type d"
5873
5874 test_56k() {
5875         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5876
5877         setup_56_special $dir $NUMFILES $NUMDIRS
5878
5879         local expected=$(((NUMDIRS + 1) * NUMFILES))
5880         local cmd="$LFS find -type f $dir"
5881         local nums=$($cmd | wc -l)
5882
5883         [ $nums -eq $expected ] ||
5884                 error "'$cmd' wrong: found $nums, expected $expected"
5885 }
5886 run_test 56k "check lfs find -type f"
5887
5888 test_56l() {
5889         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5890
5891         setup_56_special $dir $NUMFILES $NUMDIRS
5892
5893         local expected=$((NUMDIRS + NUMFILES))
5894         local cmd="$LFS find -type b $dir"
5895         local nums=$($cmd | wc -l)
5896
5897         [ $nums -eq $expected ] ||
5898                 error "'$cmd' wrong: found $nums, expected $expected"
5899 }
5900 run_test 56l "check lfs find -type b"
5901
5902 test_56m() {
5903         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5904
5905         setup_56_special $dir $NUMFILES $NUMDIRS
5906
5907         local expected=$((NUMDIRS + NUMFILES))
5908         local cmd="$LFS find -type c $dir"
5909         local nums=$($cmd | wc -l)
5910         [ $nums -eq $expected ] ||
5911                 error "'$cmd' wrong: found $nums, expected $expected"
5912 }
5913 run_test 56m "check lfs find -type c"
5914
5915 test_56n() {
5916         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5917         setup_56_special $dir $NUMFILES $NUMDIRS
5918
5919         local expected=$((NUMDIRS + NUMFILES))
5920         local cmd="$LFS find -type l $dir"
5921         local nums=$($cmd | wc -l)
5922
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925 }
5926 run_test 56n "check lfs find -type l"
5927
5928 test_56o() {
5929         local dir=$DIR/$tdir
5930
5931         setup_56 $dir $NUMFILES $NUMDIRS
5932         utime $dir/file1 > /dev/null || error "utime (1)"
5933         utime $dir/file2 > /dev/null || error "utime (2)"
5934         utime $dir/dir1 > /dev/null || error "utime (3)"
5935         utime $dir/dir2 > /dev/null || error "utime (4)"
5936         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5937         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5938
5939         local expected=4
5940         local nums=$($LFS find -mtime +0 $dir | wc -l)
5941
5942         [ $nums -eq $expected ] ||
5943                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5944
5945         expected=12
5946         cmd="$LFS find -mtime 0 $dir"
5947         nums=$($cmd | wc -l)
5948         [ $nums -eq $expected ] ||
5949                 error "'$cmd' wrong: found $nums, expected $expected"
5950 }
5951 run_test 56o "check lfs find -mtime for old files"
5952
5953 test_56ob() {
5954         local dir=$DIR/$tdir
5955         local expected=1
5956         local count=0
5957
5958         # just to make sure there is something that won't be found
5959         test_mkdir $dir
5960         touch $dir/$tfile.now
5961
5962         for age in year week day hour min; do
5963                 count=$((count + 1))
5964
5965                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5966                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5967                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5968
5969                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5970                 local nums=$($cmd | wc -l)
5971                 [ $nums -eq $expected ] ||
5972                         error "'$cmd' wrong: found $nums, expected $expected"
5973
5974                 cmd="$LFS find $dir -atime $count${age:0:1}"
5975                 nums=$($cmd | wc -l)
5976                 [ $nums -eq $expected ] ||
5977                         error "'$cmd' wrong: found $nums, expected $expected"
5978         done
5979
5980         sleep 2
5981         cmd="$LFS find $dir -ctime +1s -type f"
5982         nums=$($cmd | wc -l)
5983         (( $nums == $count * 2 + 1)) ||
5984                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5985 }
5986 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5987
5988 test_newerXY_base() {
5989         local x=$1
5990         local y=$2
5991         local dir=$DIR/$tdir
5992         local ref
5993         local negref
5994
5995         if [ $y == "t" ]; then
5996                 if [ $x == "b" ]; then
5997                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5998                 else
5999                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6000                 fi
6001         else
6002                 ref=$DIR/$tfile.newer.$x$y
6003                 touch $ref || error "touch $ref failed"
6004         fi
6005
6006         echo "before = $ref"
6007         sleep 2
6008         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6009         sleep 2
6010         if [ $y == "t" ]; then
6011                 if [ $x == "b" ]; then
6012                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6013                 else
6014                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6015                 fi
6016         else
6017                 negref=$DIR/$tfile.negnewer.$x$y
6018                 touch $negref || error "touch $negref failed"
6019         fi
6020
6021         echo "after = $negref"
6022         local cmd="$LFS find $dir -newer$x$y $ref"
6023         local nums=$(eval $cmd | wc -l)
6024         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6025
6026         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6027                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6028
6029         cmd="$LFS find $dir ! -newer$x$y $negref"
6030         nums=$(eval $cmd | wc -l)
6031         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6032                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6033
6034         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6035         nums=$(eval $cmd | wc -l)
6036         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6037                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6038
6039         rm -rf $DIR/*
6040 }
6041
6042 test_56oc() {
6043         test_newerXY_base "a" "a"
6044         test_newerXY_base "a" "m"
6045         test_newerXY_base "a" "c"
6046         test_newerXY_base "m" "a"
6047         test_newerXY_base "m" "m"
6048         test_newerXY_base "m" "c"
6049         test_newerXY_base "c" "a"
6050         test_newerXY_base "c" "m"
6051         test_newerXY_base "c" "c"
6052
6053         [[ -n "$sles_version" ]] &&
6054                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6055
6056         test_newerXY_base "a" "t"
6057         test_newerXY_base "m" "t"
6058         test_newerXY_base "c" "t"
6059
6060         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6061            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6062                 ! btime_supported && echo "btime unsupported" && return 0
6063
6064         test_newerXY_base "b" "b"
6065         test_newerXY_base "b" "t"
6066 }
6067 run_test 56oc "check lfs find -newerXY work"
6068
6069 btime_supported() {
6070         local dir=$DIR/$tdir
6071         local rc
6072
6073         mkdir -p $dir
6074         touch $dir/$tfile
6075         $LFS find $dir -btime -1d -type f
6076         rc=$?
6077         rm -rf $dir
6078         return $rc
6079 }
6080
6081 test_56od() {
6082         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6083                 ! btime_supported && skip "btime unsupported on MDS"
6084
6085         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6086                 ! btime_supported && skip "btime unsupported on clients"
6087
6088         local dir=$DIR/$tdir
6089         local ref=$DIR/$tfile.ref
6090         local negref=$DIR/$tfile.negref
6091
6092         mkdir $dir || error "mkdir $dir failed"
6093         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6094         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6095         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6096         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6097         touch $ref || error "touch $ref failed"
6098         # sleep 3 seconds at least
6099         sleep 3
6100
6101         local before=$(do_facet mds1 date +%s)
6102         local skew=$(($(date +%s) - before + 1))
6103
6104         if (( skew < 0 && skew > -5 )); then
6105                 sleep $((0 - skew + 1))
6106                 skew=0
6107         fi
6108
6109         # Set the dir stripe params to limit files all on MDT0,
6110         # otherwise we need to calc the max clock skew between
6111         # the client and MDTs.
6112         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6113         sleep 2
6114         touch $negref || error "touch $negref failed"
6115
6116         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6117         local nums=$($cmd | wc -l)
6118         local expected=$(((NUMFILES + 1) * NUMDIRS))
6119
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122
6123         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6124         nums=$($cmd | wc -l)
6125         expected=$((NUMFILES + 1))
6126         [ $nums -eq $expected ] ||
6127                 error "'$cmd' wrong: found $nums, expected $expected"
6128
6129         [ $skew -lt 0 ] && return
6130
6131         local after=$(do_facet mds1 date +%s)
6132         local age=$((after - before + 1 + skew))
6133
6134         cmd="$LFS find $dir -btime -${age}s -type f"
6135         nums=$($cmd | wc -l)
6136         expected=$(((NUMFILES + 1) * NUMDIRS))
6137
6138         echo "Clock skew between client and server: $skew, age:$age"
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=$(($NUMDIRS + 1))
6143         cmd="$LFS find $dir -btime -${age}s -type d"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147         rm -f $ref $negref || error "Failed to remove $ref $negref"
6148 }
6149 run_test 56od "check lfs find -btime with units"
6150
6151 test_56p() {
6152         [ $RUNAS_ID -eq $UID ] &&
6153                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6154
6155         local dir=$DIR/$tdir
6156
6157         setup_56 $dir $NUMFILES $NUMDIRS
6158         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6159
6160         local expected=$NUMFILES
6161         local cmd="$LFS find -uid $RUNAS_ID $dir"
6162         local nums=$($cmd | wc -l)
6163
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6168         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6169         nums=$($cmd | wc -l)
6170         [ $nums -eq $expected ] ||
6171                 error "'$cmd' wrong: found $nums, expected $expected"
6172 }
6173 run_test 56p "check lfs find -uid and ! -uid"
6174
6175 test_56q() {
6176         [ $RUNAS_ID -eq $UID ] &&
6177                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6178
6179         local dir=$DIR/$tdir
6180
6181         setup_56 $dir $NUMFILES $NUMDIRS
6182         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6183
6184         local expected=$NUMFILES
6185         local cmd="$LFS find -gid $RUNAS_GID $dir"
6186         local nums=$($cmd | wc -l)
6187
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190
6191         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6192         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56q "check lfs find -gid and ! -gid"
6198
6199 test_56r() {
6200         local dir=$DIR/$tdir
6201
6202         setup_56 $dir $NUMFILES $NUMDIRS
6203
6204         local expected=12
6205         local cmd="$LFS find -size 0 -type f -lazy $dir"
6206         local nums=$($cmd | wc -l)
6207
6208         [ $nums -eq $expected ] ||
6209                 error "'$cmd' wrong: found $nums, expected $expected"
6210         cmd="$LFS find -size 0 -type f $dir"
6211         nums=$($cmd | wc -l)
6212         [ $nums -eq $expected ] ||
6213                 error "'$cmd' wrong: found $nums, expected $expected"
6214
6215         expected=0
6216         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6217         nums=$($cmd | wc -l)
6218         [ $nums -eq $expected ] ||
6219                 error "'$cmd' wrong: found $nums, expected $expected"
6220         cmd="$LFS find ! -size 0 -type f $dir"
6221         nums=$($cmd | wc -l)
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224
6225         echo "test" > $dir/$tfile
6226         echo "test2" > $dir/$tfile.2 && sync
6227         expected=1
6228         cmd="$LFS find -size 5 -type f -lazy $dir"
6229         nums=$($cmd | wc -l)
6230         [ $nums -eq $expected ] ||
6231                 error "'$cmd' wrong: found $nums, expected $expected"
6232         cmd="$LFS find -size 5 -type f $dir"
6233         nums=$($cmd | wc -l)
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236
6237         expected=1
6238         cmd="$LFS find -size +5 -type f -lazy $dir"
6239         nums=$($cmd | wc -l)
6240         [ $nums -eq $expected ] ||
6241                 error "'$cmd' wrong: found $nums, expected $expected"
6242         cmd="$LFS find -size +5 -type f $dir"
6243         nums=$($cmd | wc -l)
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246
6247         expected=2
6248         cmd="$LFS find -size +0 -type f -lazy $dir"
6249         nums=$($cmd | wc -l)
6250         [ $nums -eq $expected ] ||
6251                 error "'$cmd' wrong: found $nums, expected $expected"
6252         cmd="$LFS find -size +0 -type f $dir"
6253         nums=$($cmd | wc -l)
6254         [ $nums -eq $expected ] ||
6255                 error "'$cmd' wrong: found $nums, expected $expected"
6256
6257         expected=2
6258         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6259         nums=$($cmd | wc -l)
6260         [ $nums -eq $expected ] ||
6261                 error "'$cmd' wrong: found $nums, expected $expected"
6262         cmd="$LFS find ! -size -5 -type f $dir"
6263         nums=$($cmd | wc -l)
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266
6267         expected=12
6268         cmd="$LFS find -size -5 -type f -lazy $dir"
6269         nums=$($cmd | wc -l)
6270         [ $nums -eq $expected ] ||
6271                 error "'$cmd' wrong: found $nums, expected $expected"
6272         cmd="$LFS find -size -5 -type f $dir"
6273         nums=$($cmd | wc -l)
6274         [ $nums -eq $expected ] ||
6275                 error "'$cmd' wrong: found $nums, expected $expected"
6276 }
6277 run_test 56r "check lfs find -size works"
6278
6279 test_56ra_sub() {
6280         local expected=$1
6281         local glimpses=$2
6282         local cmd="$3"
6283
6284         cancel_lru_locks $OSC
6285
6286         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6287         local nums=$($cmd | wc -l)
6288
6289         [ $nums -eq $expected ] ||
6290                 error "'$cmd' wrong: found $nums, expected $expected"
6291
6292         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6293
6294         if (( rpcs_before + glimpses != rpcs_after )); then
6295                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6296                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6297
6298                 if [[ $glimpses == 0 ]]; then
6299                         error "'$cmd' should not send glimpse RPCs to OST"
6300                 else
6301                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6302                 fi
6303         fi
6304 }
6305
6306 test_56ra() {
6307         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6308                 skip "MDS < 2.12.58 doesn't return LSOM data"
6309         local dir=$DIR/$tdir
6310         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6311
6312         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6313
6314         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6315         $LCTL set_param -n llite.*.statahead_agl=0
6316         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6317
6318         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6319         # open and close all files to ensure LSOM is updated
6320         cancel_lru_locks $OSC
6321         find $dir -type f | xargs cat > /dev/null
6322
6323         #   expect_found  glimpse_rpcs  command_to_run
6324         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6325         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6326         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6327         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6328
6329         echo "test" > $dir/$tfile
6330         echo "test2" > $dir/$tfile.2 && sync
6331         cancel_lru_locks $OSC
6332         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6333
6334         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6335         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6336         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6337         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6338
6339         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6340         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6341         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6342         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6343         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6344         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6345 }
6346 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6347
6348 test_56rb() {
6349         local dir=$DIR/$tdir
6350         local tmp=$TMP/$tfile.log
6351         local mdt_idx;
6352
6353         test_mkdir -p $dir || error "failed to mkdir $dir"
6354         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6355                 error "failed to setstripe $dir/$tfile"
6356         mdt_idx=$($LFS getdirstripe -i $dir)
6357         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6358
6359         stack_trap "rm -f $tmp" EXIT
6360         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6361         ! grep -q obd_uuid $tmp ||
6362                 error "failed to find --size +100K --ost 0 $dir"
6363         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6364         ! grep -q obd_uuid $tmp ||
6365                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6366 }
6367 run_test 56rb "check lfs find --size --ost/--mdt works"
6368
6369 test_56s() { # LU-611 #LU-9369
6370         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6371
6372         local dir=$DIR/$tdir
6373         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6374
6375         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6376         for i in $(seq $NUMDIRS); do
6377                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6378         done
6379
6380         local expected=$NUMDIRS
6381         local cmd="$LFS find -c $OSTCOUNT $dir"
6382         local nums=$($cmd | wc -l)
6383
6384         [ $nums -eq $expected ] || {
6385                 $LFS getstripe -R $dir
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387         }
6388
6389         expected=$((NUMDIRS + onestripe))
6390         cmd="$LFS find -stripe-count +0 -type f $dir"
6391         nums=$($cmd | wc -l)
6392         [ $nums -eq $expected ] || {
6393                 $LFS getstripe -R $dir
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395         }
6396
6397         expected=$onestripe
6398         cmd="$LFS find -stripe-count 1 -type f $dir"
6399         nums=$($cmd | wc -l)
6400         [ $nums -eq $expected ] || {
6401                 $LFS getstripe -R $dir
6402                 error "'$cmd' wrong: found $nums, expected $expected"
6403         }
6404
6405         cmd="$LFS find -stripe-count -2 -type f $dir"
6406         nums=$($cmd | wc -l)
6407         [ $nums -eq $expected ] || {
6408                 $LFS getstripe -R $dir
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410         }
6411
6412         expected=0
6413         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6414         nums=$($cmd | wc -l)
6415         [ $nums -eq $expected ] || {
6416                 $LFS getstripe -R $dir
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418         }
6419 }
6420 run_test 56s "check lfs find -stripe-count works"
6421
6422 test_56t() { # LU-611 #LU-9369
6423         local dir=$DIR/$tdir
6424
6425         setup_56 $dir 0 $NUMDIRS
6426         for i in $(seq $NUMDIRS); do
6427                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6428         done
6429
6430         local expected=$NUMDIRS
6431         local cmd="$LFS find -S 8M $dir"
6432         local nums=$($cmd | wc -l)
6433
6434         [ $nums -eq $expected ] || {
6435                 $LFS getstripe -R $dir
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437         }
6438         rm -rf $dir
6439
6440         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6441
6442         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6443
6444         expected=$(((NUMDIRS + 1) * NUMFILES))
6445         cmd="$LFS find -stripe-size 512k -type f $dir"
6446         nums=$($cmd | wc -l)
6447         [ $nums -eq $expected ] ||
6448                 error "'$cmd' wrong: found $nums, expected $expected"
6449
6450         cmd="$LFS find -stripe-size +320k -type f $dir"
6451         nums=$($cmd | wc -l)
6452         [ $nums -eq $expected ] ||
6453                 error "'$cmd' wrong: found $nums, expected $expected"
6454
6455         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6456         cmd="$LFS find -stripe-size +200k -type f $dir"
6457         nums=$($cmd | wc -l)
6458         [ $nums -eq $expected ] ||
6459                 error "'$cmd' wrong: found $nums, expected $expected"
6460
6461         cmd="$LFS find -stripe-size -640k -type f $dir"
6462         nums=$($cmd | wc -l)
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465
6466         expected=4
6467         cmd="$LFS find -stripe-size 256k -type f $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         cmd="$LFS find -stripe-size -320k -type f $dir"
6473         nums=$($cmd | wc -l)
6474         [ $nums -eq $expected ] ||
6475                 error "'$cmd' wrong: found $nums, expected $expected"
6476
6477         expected=0
6478         cmd="$LFS find -stripe-size 1024k -type f $dir"
6479         nums=$($cmd | wc -l)
6480         [ $nums -eq $expected ] ||
6481                 error "'$cmd' wrong: found $nums, expected $expected"
6482 }
6483 run_test 56t "check lfs find -stripe-size works"
6484
6485 test_56u() { # LU-611
6486         local dir=$DIR/$tdir
6487
6488         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6489
6490         if [[ $OSTCOUNT -gt 1 ]]; then
6491                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6492                 onestripe=4
6493         else
6494                 onestripe=0
6495         fi
6496
6497         local expected=$(((NUMDIRS + 1) * NUMFILES))
6498         local cmd="$LFS find -stripe-index 0 -type f $dir"
6499         local nums=$($cmd | wc -l)
6500
6501         [ $nums -eq $expected ] ||
6502                 error "'$cmd' wrong: found $nums, expected $expected"
6503
6504         expected=$onestripe
6505         cmd="$LFS find -stripe-index 1 -type f $dir"
6506         nums=$($cmd | wc -l)
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509
6510         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6511         nums=$($cmd | wc -l)
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=0
6516         # This should produce an error and not return any files
6517         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6518         nums=$($cmd 2>/dev/null | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521
6522         if [[ $OSTCOUNT -gt 1 ]]; then
6523                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6524                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6525                 nums=$($cmd | wc -l)
6526                 [ $nums -eq $expected ] ||
6527                         error "'$cmd' wrong: found $nums, expected $expected"
6528         fi
6529 }
6530 run_test 56u "check lfs find -stripe-index works"
6531
6532 test_56v() {
6533         local mdt_idx=0
6534         local dir=$DIR/$tdir
6535
6536         setup_56 $dir $NUMFILES $NUMDIRS
6537
6538         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6539         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6540
6541         for file in $($LFS find -m $UUID $dir); do
6542                 file_midx=$($LFS getstripe -m $file)
6543                 [ $file_midx -eq $mdt_idx ] ||
6544                         error "lfs find -m $UUID != getstripe -m $file_midx"
6545         done
6546 }
6547 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6548
6549 test_56w() {
6550         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6552
6553         local dir=$DIR/$tdir
6554
6555         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6556
6557         local stripe_size=$($LFS getstripe -S -d $dir) ||
6558                 error "$LFS getstripe -S -d $dir failed"
6559         stripe_size=${stripe_size%% *}
6560
6561         local file_size=$((stripe_size * OSTCOUNT))
6562         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6563         local required_space=$((file_num * file_size))
6564         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6565                            head -n1)
6566         [[ $free_space -le $((required_space / 1024)) ]] &&
6567                 skip_env "need $required_space, have $free_space kbytes"
6568
6569         local dd_bs=65536
6570         local dd_count=$((file_size / dd_bs))
6571
6572         # write data into the files
6573         local i
6574         local j
6575         local file
6576
6577         for i in $(seq $NUMFILES); do
6578                 file=$dir/file$i
6579                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6580                         error "write data into $file failed"
6581         done
6582         for i in $(seq $NUMDIRS); do
6583                 for j in $(seq $NUMFILES); do
6584                         file=$dir/dir$i/file$j
6585                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6586                                 error "write data into $file failed"
6587                 done
6588         done
6589
6590         # $LFS_MIGRATE will fail if hard link migration is unsupported
6591         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6592                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6593                         error "creating links to $dir/dir1/file1 failed"
6594         fi
6595
6596         local expected=-1
6597
6598         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6599
6600         # lfs_migrate file
6601         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6602
6603         echo "$cmd"
6604         eval $cmd || error "$cmd failed"
6605
6606         check_stripe_count $dir/file1 $expected
6607
6608         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6609         then
6610                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6611                 # OST 1 if it is on OST 0. This file is small enough to
6612                 # be on only one stripe.
6613                 file=$dir/migr_1_ost
6614                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6615                         error "write data into $file failed"
6616                 local obdidx=$($LFS getstripe -i $file)
6617                 local oldmd5=$(md5sum $file)
6618                 local newobdidx=0
6619
6620                 [[ $obdidx -eq 0 ]] && newobdidx=1
6621                 cmd="$LFS migrate -i $newobdidx $file"
6622                 echo $cmd
6623                 eval $cmd || error "$cmd failed"
6624
6625                 local realobdix=$($LFS getstripe -i $file)
6626                 local newmd5=$(md5sum $file)
6627
6628                 [[ $newobdidx -ne $realobdix ]] &&
6629                         error "new OST is different (was=$obdidx, "\
6630                               "wanted=$newobdidx, got=$realobdix)"
6631                 [[ "$oldmd5" != "$newmd5" ]] &&
6632                         error "md5sum differ: $oldmd5, $newmd5"
6633         fi
6634
6635         # lfs_migrate dir
6636         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6637         echo "$cmd"
6638         eval $cmd || error "$cmd failed"
6639
6640         for j in $(seq $NUMFILES); do
6641                 check_stripe_count $dir/dir1/file$j $expected
6642         done
6643
6644         # lfs_migrate works with lfs find
6645         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6646              $LFS_MIGRATE -y -c $expected"
6647         echo "$cmd"
6648         eval $cmd || error "$cmd failed"
6649
6650         for i in $(seq 2 $NUMFILES); do
6651                 check_stripe_count $dir/file$i $expected
6652         done
6653         for i in $(seq 2 $NUMDIRS); do
6654                 for j in $(seq $NUMFILES); do
6655                 check_stripe_count $dir/dir$i/file$j $expected
6656                 done
6657         done
6658 }
6659 run_test 56w "check lfs_migrate -c stripe_count works"
6660
6661 test_56wb() {
6662         local file1=$DIR/$tdir/file1
6663         local create_pool=false
6664         local initial_pool=$($LFS getstripe -p $DIR)
6665         local pool_list=()
6666         local pool=""
6667
6668         echo -n "Creating test dir..."
6669         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6670         echo "done."
6671
6672         echo -n "Creating test file..."
6673         touch $file1 || error "cannot create file"
6674         echo "done."
6675
6676         echo -n "Detecting existing pools..."
6677         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6678
6679         if [ ${#pool_list[@]} -gt 0 ]; then
6680                 echo "${pool_list[@]}"
6681                 for thispool in "${pool_list[@]}"; do
6682                         if [[ -z "$initial_pool" ||
6683                               "$initial_pool" != "$thispool" ]]; then
6684                                 pool="$thispool"
6685                                 echo "Using existing pool '$pool'"
6686                                 break
6687                         fi
6688                 done
6689         else
6690                 echo "none detected."
6691         fi
6692         if [ -z "$pool" ]; then
6693                 pool=${POOL:-testpool}
6694                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6695                 echo -n "Creating pool '$pool'..."
6696                 create_pool=true
6697                 pool_add $pool &> /dev/null ||
6698                         error "pool_add failed"
6699                 echo "done."
6700
6701                 echo -n "Adding target to pool..."
6702                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6703                         error "pool_add_targets failed"
6704                 echo "done."
6705         fi
6706
6707         echo -n "Setting pool using -p option..."
6708         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6709                 error "migrate failed rc = $?"
6710         echo "done."
6711
6712         echo -n "Verifying test file is in pool after migrating..."
6713         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6714                 error "file was not migrated to pool $pool"
6715         echo "done."
6716
6717         echo -n "Removing test file from pool '$pool'..."
6718         # "lfs migrate $file" won't remove the file from the pool
6719         # until some striping information is changed.
6720         $LFS migrate -c 1 $file1 &> /dev/null ||
6721                 error "cannot remove from pool"
6722         [ "$($LFS getstripe -p $file1)" ] &&
6723                 error "pool still set"
6724         echo "done."
6725
6726         echo -n "Setting pool using --pool option..."
6727         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6728                 error "migrate failed rc = $?"
6729         echo "done."
6730
6731         # Clean up
6732         rm -f $file1
6733         if $create_pool; then
6734                 destroy_test_pools 2> /dev/null ||
6735                         error "destroy test pools failed"
6736         fi
6737 }
6738 run_test 56wb "check lfs_migrate pool support"
6739
6740 test_56wc() {
6741         local file1="$DIR/$tdir/file1"
6742         local parent_ssize
6743         local parent_scount
6744         local cur_ssize
6745         local cur_scount
6746         local orig_ssize
6747
6748         echo -n "Creating test dir..."
6749         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6750         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6751                 error "cannot set stripe by '-S 1M -c 1'"
6752         echo "done"
6753
6754         echo -n "Setting initial stripe for test file..."
6755         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6756                 error "cannot set stripe"
6757         cur_ssize=$($LFS getstripe -S "$file1")
6758         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6759         echo "done."
6760
6761         # File currently set to -S 512K -c 1
6762
6763         # Ensure -c and -S options are rejected when -R is set
6764         echo -n "Verifying incompatible options are detected..."
6765         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6766                 error "incompatible -c and -R options not detected"
6767         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6768                 error "incompatible -S and -R options not detected"
6769         echo "done."
6770
6771         # Ensure unrecognized options are passed through to 'lfs migrate'
6772         echo -n "Verifying -S option is passed through to lfs migrate..."
6773         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6774                 error "migration failed"
6775         cur_ssize=$($LFS getstripe -S "$file1")
6776         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6777         echo "done."
6778
6779         # File currently set to -S 1M -c 1
6780
6781         # Ensure long options are supported
6782         echo -n "Verifying long options supported..."
6783         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6784                 error "long option without argument not supported"
6785         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6786                 error "long option with argument not supported"
6787         cur_ssize=$($LFS getstripe -S "$file1")
6788         [ $cur_ssize -eq 524288 ] ||
6789                 error "migrate --stripe-size $cur_ssize != 524288"
6790         echo "done."
6791
6792         # File currently set to -S 512K -c 1
6793
6794         if [ "$OSTCOUNT" -gt 1 ]; then
6795                 echo -n "Verifying explicit stripe count can be set..."
6796                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6797                         error "migrate failed"
6798                 cur_scount=$($LFS getstripe -c "$file1")
6799                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6800                 echo "done."
6801         fi
6802
6803         # File currently set to -S 512K -c 1 or -S 512K -c 2
6804
6805         # Ensure parent striping is used if -R is set, and no stripe
6806         # count or size is specified
6807         echo -n "Setting stripe for parent directory..."
6808         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6809                 error "cannot set stripe '-S 2M -c 1'"
6810         echo "done."
6811
6812         echo -n "Verifying restripe option uses parent stripe settings..."
6813         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6814         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6815         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6816                 error "migrate failed"
6817         cur_ssize=$($LFS getstripe -S "$file1")
6818         [ $cur_ssize -eq $parent_ssize ] ||
6819                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6820         cur_scount=$($LFS getstripe -c "$file1")
6821         [ $cur_scount -eq $parent_scount ] ||
6822                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6823         echo "done."
6824
6825         # File currently set to -S 1M -c 1
6826
6827         # Ensure striping is preserved if -R is not set, and no stripe
6828         # count or size is specified
6829         echo -n "Verifying striping size preserved when not specified..."
6830         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6831         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6832                 error "cannot set stripe on parent directory"
6833         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6834                 error "migrate failed"
6835         cur_ssize=$($LFS getstripe -S "$file1")
6836         [ $cur_ssize -eq $orig_ssize ] ||
6837                 error "migrate by default $cur_ssize != $orig_ssize"
6838         echo "done."
6839
6840         # Ensure file name properly detected when final option has no argument
6841         echo -n "Verifying file name properly detected..."
6842         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6843                 error "file name interpreted as option argument"
6844         echo "done."
6845
6846         # Clean up
6847         rm -f "$file1"
6848 }
6849 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6850
6851 test_56wd() {
6852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6853
6854         local file1=$DIR/$tdir/file1
6855
6856         echo -n "Creating test dir..."
6857         test_mkdir $DIR/$tdir || error "cannot create dir"
6858         echo "done."
6859
6860         echo -n "Creating test file..."
6861         touch $file1
6862         echo "done."
6863
6864         # Ensure 'lfs migrate' will fail by using a non-existent option,
6865         # and make sure rsync is not called to recover
6866         echo -n "Make sure --no-rsync option works..."
6867         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6868                 grep -q 'refusing to fall back to rsync' ||
6869                 error "rsync was called with --no-rsync set"
6870         echo "done."
6871
6872         # Ensure rsync is called without trying 'lfs migrate' first
6873         echo -n "Make sure --rsync option works..."
6874         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6875                 grep -q 'falling back to rsync' &&
6876                 error "lfs migrate was called with --rsync set"
6877         echo "done."
6878
6879         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6880         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6881                 grep -q 'at the same time' ||
6882                 error "--rsync and --no-rsync accepted concurrently"
6883         echo "done."
6884
6885         # Clean up
6886         rm -f $file1
6887 }
6888 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6889
6890 test_56we() {
6891         local td=$DIR/$tdir
6892         local tf=$td/$tfile
6893
6894         test_mkdir $td || error "cannot create $td"
6895         touch $tf || error "cannot touch $tf"
6896
6897         echo -n "Make sure --non-direct|-D works..."
6898         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6899                 grep -q "lfs migrate --non-direct" ||
6900                 error "--non-direct option cannot work correctly"
6901         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6902                 grep -q "lfs migrate -D" ||
6903                 error "-D option cannot work correctly"
6904         echo "done."
6905 }
6906 run_test 56we "check lfs_migrate --non-direct|-D support"
6907
6908 test_56x() {
6909         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6910         check_swap_layouts_support
6911
6912         local dir=$DIR/$tdir
6913         local ref1=/etc/passwd
6914         local file1=$dir/file1
6915
6916         test_mkdir $dir || error "creating dir $dir"
6917         $LFS setstripe -c 2 $file1
6918         cp $ref1 $file1
6919         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6920         stripe=$($LFS getstripe -c $file1)
6921         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6922         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6923
6924         # clean up
6925         rm -f $file1
6926 }
6927 run_test 56x "lfs migration support"
6928
6929 test_56xa() {
6930         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6931         check_swap_layouts_support
6932
6933         local dir=$DIR/$tdir/$testnum
6934
6935         test_mkdir -p $dir
6936
6937         local ref1=/etc/passwd
6938         local file1=$dir/file1
6939
6940         $LFS setstripe -c 2 $file1
6941         cp $ref1 $file1
6942         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6943
6944         local stripe=$($LFS getstripe -c $file1)
6945
6946         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6947         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6948
6949         # clean up
6950         rm -f $file1
6951 }
6952 run_test 56xa "lfs migration --block support"
6953
6954 check_migrate_links() {
6955         local dir="$1"
6956         local file1="$dir/file1"
6957         local begin="$2"
6958         local count="$3"
6959         local runas="$4"
6960         local total_count=$(($begin + $count - 1))
6961         local symlink_count=10
6962         local uniq_count=10
6963
6964         if [ ! -f "$file1" ]; then
6965                 echo -n "creating initial file..."
6966                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6967                         error "cannot setstripe initial file"
6968                 echo "done"
6969
6970                 echo -n "creating symlinks..."
6971                 for s in $(seq 1 $symlink_count); do
6972                         ln -s "$file1" "$dir/slink$s" ||
6973                                 error "cannot create symlinks"
6974                 done
6975                 echo "done"
6976
6977                 echo -n "creating nonlinked files..."
6978                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6979                         error "cannot create nonlinked files"
6980                 echo "done"
6981         fi
6982
6983         # create hard links
6984         if [ ! -f "$dir/file$total_count" ]; then
6985                 echo -n "creating hard links $begin:$total_count..."
6986                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6987                         /dev/null || error "cannot create hard links"
6988                 echo "done"
6989         fi
6990
6991         echo -n "checking number of hard links listed in xattrs..."
6992         local fid=$($LFS getstripe -F "$file1")
6993         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6994
6995         echo "${#paths[*]}"
6996         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6997                         skip "hard link list has unexpected size, skipping test"
6998         fi
6999         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7000                         error "link names should exceed xattrs size"
7001         fi
7002
7003         echo -n "migrating files..."
7004         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7005         local rc=$?
7006         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7007         echo "done"
7008
7009         # make sure all links have been properly migrated
7010         echo -n "verifying files..."
7011         fid=$($LFS getstripe -F "$file1") ||
7012                 error "cannot get fid for file $file1"
7013         for i in $(seq 2 $total_count); do
7014                 local fid2=$($LFS getstripe -F $dir/file$i)
7015
7016                 [ "$fid2" == "$fid" ] ||
7017                         error "migrated hard link has mismatched FID"
7018         done
7019
7020         # make sure hard links were properly detected, and migration was
7021         # performed only once for the entire link set; nonlinked files should
7022         # also be migrated
7023         local actual=$(grep -c 'done' <<< "$migrate_out")
7024         local expected=$(($uniq_count + 1))
7025
7026         [ "$actual" -eq  "$expected" ] ||
7027                 error "hard links individually migrated ($actual != $expected)"
7028
7029         # make sure the correct number of hard links are present
7030         local hardlinks=$(stat -c '%h' "$file1")
7031
7032         [ $hardlinks -eq $total_count ] ||
7033                 error "num hard links $hardlinks != $total_count"
7034         echo "done"
7035
7036         return 0
7037 }
7038
7039 test_56xb() {
7040         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7041                 skip "Need MDS version at least 2.10.55"
7042
7043         local dir="$DIR/$tdir"
7044
7045         test_mkdir "$dir" || error "cannot create dir $dir"
7046
7047         echo "testing lfs migrate mode when all links fit within xattrs"
7048         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7049
7050         echo "testing rsync mode when all links fit within xattrs"
7051         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7052
7053         echo "testing lfs migrate mode when all links do not fit within xattrs"
7054         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7055
7056         echo "testing rsync mode when all links do not fit within xattrs"
7057         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7058
7059         chown -R $RUNAS_ID $dir
7060         echo "testing non-root lfs migrate mode when not all links are in xattr"
7061         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7062
7063         # clean up
7064         rm -rf $dir
7065 }
7066 run_test 56xb "lfs migration hard link support"
7067
7068 test_56xc() {
7069         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7070
7071         local dir="$DIR/$tdir"
7072
7073         test_mkdir "$dir" || error "cannot create dir $dir"
7074
7075         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7076         echo -n "Setting initial stripe for 20MB test file..."
7077         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7078                 error "cannot setstripe 20MB file"
7079         echo "done"
7080         echo -n "Sizing 20MB test file..."
7081         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7082         echo "done"
7083         echo -n "Verifying small file autostripe count is 1..."
7084         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7085                 error "cannot migrate 20MB file"
7086         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7087                 error "cannot get stripe for $dir/20mb"
7088         [ $stripe_count -eq 1 ] ||
7089                 error "unexpected stripe count $stripe_count for 20MB file"
7090         rm -f "$dir/20mb"
7091         echo "done"
7092
7093         # Test 2: File is small enough to fit within the available space on
7094         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7095         # have at least an additional 1KB for each desired stripe for test 3
7096         echo -n "Setting stripe for 1GB test file..."
7097         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7098         echo "done"
7099         echo -n "Sizing 1GB test file..."
7100         # File size is 1GB + 3KB
7101         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7102         echo "done"
7103
7104         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7105         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7106         if (( avail > 524288 * OSTCOUNT )); then
7107                 echo -n "Migrating 1GB file..."
7108                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7109                         error "cannot migrate 1GB file"
7110                 echo "done"
7111                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7112                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7113                         error "cannot getstripe for 1GB file"
7114                 [ $stripe_count -eq 2 ] ||
7115                         error "unexpected stripe count $stripe_count != 2"
7116                 echo "done"
7117         fi
7118
7119         # Test 3: File is too large to fit within the available space on
7120         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7121         if [ $OSTCOUNT -ge 3 ]; then
7122                 # The required available space is calculated as
7123                 # file size (1GB + 3KB) / OST count (3).
7124                 local kb_per_ost=349526
7125
7126                 echo -n "Migrating 1GB file with limit..."
7127                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7128                         error "cannot migrate 1GB file with limit"
7129                 echo "done"
7130
7131                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7132                 echo -n "Verifying 1GB autostripe count with limited space..."
7133                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7134                         error "unexpected stripe count $stripe_count (min 3)"
7135                 echo "done"
7136         fi
7137
7138         # clean up
7139         rm -rf $dir
7140 }
7141 run_test 56xc "lfs migration autostripe"
7142
7143 test_56xd() {
7144         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7145
7146         local dir=$DIR/$tdir
7147         local f_mgrt=$dir/$tfile.mgrt
7148         local f_yaml=$dir/$tfile.yaml
7149         local f_copy=$dir/$tfile.copy
7150         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7151         local layout_copy="-c 2 -S 2M -i 1"
7152         local yamlfile=$dir/yamlfile
7153         local layout_before;
7154         local layout_after;
7155
7156         test_mkdir "$dir" || error "cannot create dir $dir"
7157         $LFS setstripe $layout_yaml $f_yaml ||
7158                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7159         $LFS getstripe --yaml $f_yaml > $yamlfile
7160         $LFS setstripe $layout_copy $f_copy ||
7161                 error "cannot setstripe $f_copy with layout $layout_copy"
7162         touch $f_mgrt
7163         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7164
7165         # 1. test option --yaml
7166         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7167                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7168         layout_before=$(get_layout_param $f_yaml)
7169         layout_after=$(get_layout_param $f_mgrt)
7170         [ "$layout_after" == "$layout_before" ] ||
7171                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7172
7173         # 2. test option --copy
7174         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7175                 error "cannot migrate $f_mgrt with --copy $f_copy"
7176         layout_before=$(get_layout_param $f_copy)
7177         layout_after=$(get_layout_param $f_mgrt)
7178         [ "$layout_after" == "$layout_before" ] ||
7179                 error "lfs_migrate --copy: $layout_after != $layout_before"
7180 }
7181 run_test 56xd "check lfs_migrate --yaml and --copy support"
7182
7183 test_56xe() {
7184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7185
7186         local dir=$DIR/$tdir
7187         local f_comp=$dir/$tfile
7188         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7189         local layout_before=""
7190         local layout_after=""
7191
7192         test_mkdir "$dir" || error "cannot create dir $dir"
7193         $LFS setstripe $layout $f_comp ||
7194                 error "cannot setstripe $f_comp with layout $layout"
7195         layout_before=$(get_layout_param $f_comp)
7196         dd if=/dev/zero of=$f_comp bs=1M count=4
7197
7198         # 1. migrate a comp layout file by lfs_migrate
7199         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7200         layout_after=$(get_layout_param $f_comp)
7201         [ "$layout_before" == "$layout_after" ] ||
7202                 error "lfs_migrate: $layout_before != $layout_after"
7203
7204         # 2. migrate a comp layout file by lfs migrate
7205         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7206         layout_after=$(get_layout_param $f_comp)
7207         [ "$layout_before" == "$layout_after" ] ||
7208                 error "lfs migrate: $layout_before != $layout_after"
7209 }
7210 run_test 56xe "migrate a composite layout file"
7211
7212 test_56xf() {
7213         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7214
7215         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7216                 skip "Need server version at least 2.13.53"
7217
7218         local dir=$DIR/$tdir
7219         local f_comp=$dir/$tfile
7220         local layout="-E 1M -c1 -E -1 -c2"
7221         local fid_before=""
7222         local fid_after=""
7223
7224         test_mkdir "$dir" || error "cannot create dir $dir"
7225         $LFS setstripe $layout $f_comp ||
7226                 error "cannot setstripe $f_comp with layout $layout"
7227         fid_before=$($LFS getstripe --fid $f_comp)
7228         dd if=/dev/zero of=$f_comp bs=1M count=4
7229
7230         # 1. migrate a comp layout file to a comp layout
7231         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7232         fid_after=$($LFS getstripe --fid $f_comp)
7233         [ "$fid_before" == "$fid_after" ] ||
7234                 error "comp-to-comp migrate: $fid_before != $fid_after"
7235
7236         # 2. migrate a comp layout file to a plain layout
7237         $LFS migrate -c2 $f_comp ||
7238                 error "cannot migrate $f_comp by lfs migrate"
7239         fid_after=$($LFS getstripe --fid $f_comp)
7240         [ "$fid_before" == "$fid_after" ] ||
7241                 error "comp-to-plain migrate: $fid_before != $fid_after"
7242
7243         # 3. migrate a plain layout file to a comp layout
7244         $LFS migrate $layout $f_comp ||
7245                 error "cannot migrate $f_comp by lfs migrate"
7246         fid_after=$($LFS getstripe --fid $f_comp)
7247         [ "$fid_before" == "$fid_after" ] ||
7248                 error "plain-to-comp migrate: $fid_before != $fid_after"
7249 }
7250 run_test 56xf "FID is not lost during migration of a composite layout file"
7251
7252 test_56y() {
7253         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7254                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7255
7256         local res=""
7257         local dir=$DIR/$tdir
7258         local f1=$dir/file1
7259         local f2=$dir/file2
7260
7261         test_mkdir -p $dir || error "creating dir $dir"
7262         touch $f1 || error "creating std file $f1"
7263         $MULTIOP $f2 H2c || error "creating released file $f2"
7264
7265         # a directory can be raid0, so ask only for files
7266         res=$($LFS find $dir -L raid0 -type f | wc -l)
7267         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7268
7269         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7270         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7271
7272         # only files can be released, so no need to force file search
7273         res=$($LFS find $dir -L released)
7274         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7275
7276         res=$($LFS find $dir -type f \! -L released)
7277         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7278 }
7279 run_test 56y "lfs find -L raid0|released"
7280
7281 test_56z() { # LU-4824
7282         # This checks to make sure 'lfs find' continues after errors
7283         # There are two classes of errors that should be caught:
7284         # - If multiple paths are provided, all should be searched even if one
7285         #   errors out
7286         # - If errors are encountered during the search, it should not terminate
7287         #   early
7288         local dir=$DIR/$tdir
7289         local i
7290
7291         test_mkdir $dir
7292         for i in d{0..9}; do
7293                 test_mkdir $dir/$i
7294                 touch $dir/$i/$tfile
7295         done
7296         $LFS find $DIR/non_existent_dir $dir &&
7297                 error "$LFS find did not return an error"
7298         # Make a directory unsearchable. This should NOT be the last entry in
7299         # directory order.  Arbitrarily pick the 6th entry
7300         chmod 700 $($LFS find $dir -type d | sed '6!d')
7301
7302         $RUNAS $LFS find $DIR/non_existent $dir
7303         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7304
7305         # The user should be able to see 10 directories and 9 files
7306         (( count == 19 )) ||
7307                 error "$LFS find found $count != 19 entries after error"
7308 }
7309 run_test 56z "lfs find should continue after an error"
7310
7311 test_56aa() { # LU-5937
7312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7313
7314         local dir=$DIR/$tdir
7315
7316         mkdir $dir
7317         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7318
7319         createmany -o $dir/striped_dir/${tfile}- 1024
7320         local dirs=$($LFS find --size +8k $dir/)
7321
7322         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7323 }
7324 run_test 56aa "lfs find --size under striped dir"
7325
7326 test_56ab() { # LU-10705
7327         test_mkdir $DIR/$tdir
7328         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7329         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7330         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7331         # Flush writes to ensure valid blocks.  Need to be more thorough for
7332         # ZFS, since blocks are not allocated/returned to client immediately.
7333         sync_all_data
7334         wait_zfs_commit ost1 2
7335         cancel_lru_locks osc
7336         ls -ls $DIR/$tdir
7337
7338         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7339
7340         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7341
7342         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7343         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7344
7345         rm -f $DIR/$tdir/$tfile.[123]
7346 }
7347 run_test 56ab "lfs find --blocks"
7348
7349 test_56ba() {
7350         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7351                 skip "Need MDS version at least 2.10.50"
7352
7353         # Create composite files with one component
7354         local dir=$DIR/$tdir
7355
7356         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7357         # Create composite files with three components
7358         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7359         # Create non-composite files
7360         createmany -o $dir/${tfile}- 10
7361
7362         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7363
7364         [[ $nfiles == 10 ]] ||
7365                 error "lfs find -E 1M found $nfiles != 10 files"
7366
7367         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7368         [[ $nfiles == 25 ]] ||
7369                 error "lfs find ! -E 1M found $nfiles != 25 files"
7370
7371         # All files have a component that starts at 0
7372         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7373         [[ $nfiles == 35 ]] ||
7374                 error "lfs find --component-start 0 - $nfiles != 35 files"
7375
7376         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7377         [[ $nfiles == 15 ]] ||
7378                 error "lfs find --component-start 2M - $nfiles != 15 files"
7379
7380         # All files created here have a componenet that does not starts at 2M
7381         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7382         [[ $nfiles == 35 ]] ||
7383                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7384
7385         # Find files with a specified number of components
7386         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7387         [[ $nfiles == 15 ]] ||
7388                 error "lfs find --component-count 3 - $nfiles != 15 files"
7389
7390         # Remember non-composite files have a component count of zero
7391         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7392         [[ $nfiles == 10 ]] ||
7393                 error "lfs find --component-count 0 - $nfiles != 10 files"
7394
7395         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7396         [[ $nfiles == 20 ]] ||
7397                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7398
7399         # All files have a flag called "init"
7400         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7401         [[ $nfiles == 35 ]] ||
7402                 error "lfs find --component-flags init - $nfiles != 35 files"
7403
7404         # Multi-component files will have a component not initialized
7405         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7406         [[ $nfiles == 15 ]] ||
7407                 error "lfs find !--component-flags init - $nfiles != 15 files"
7408
7409         rm -rf $dir
7410
7411 }
7412 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7413
7414 test_56ca() {
7415         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7416                 skip "Need MDS version at least 2.10.57"
7417
7418         local td=$DIR/$tdir
7419         local tf=$td/$tfile
7420         local dir
7421         local nfiles
7422         local cmd
7423         local i
7424         local j
7425
7426         # create mirrored directories and mirrored files
7427         mkdir $td || error "mkdir $td failed"
7428         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7429         createmany -o $tf- 10 || error "create $tf- failed"
7430
7431         for i in $(seq 2); do
7432                 dir=$td/dir$i
7433                 mkdir $dir || error "mkdir $dir failed"
7434                 $LFS mirror create -N$((3 + i)) $dir ||
7435                         error "create mirrored dir $dir failed"
7436                 createmany -o $dir/$tfile- 10 ||
7437                         error "create $dir/$tfile- failed"
7438         done
7439
7440         # change the states of some mirrored files
7441         echo foo > $tf-6
7442         for i in $(seq 2); do
7443                 dir=$td/dir$i
7444                 for j in $(seq 4 9); do
7445                         echo foo > $dir/$tfile-$j
7446                 done
7447         done
7448
7449         # find mirrored files with specific mirror count
7450         cmd="$LFS find --mirror-count 3 --type f $td"
7451         nfiles=$($cmd | wc -l)
7452         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7453
7454         cmd="$LFS find ! --mirror-count 3 --type f $td"
7455         nfiles=$($cmd | wc -l)
7456         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7457
7458         cmd="$LFS find --mirror-count +2 --type f $td"
7459         nfiles=$($cmd | wc -l)
7460         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7461
7462         cmd="$LFS find --mirror-count -6 --type f $td"
7463         nfiles=$($cmd | wc -l)
7464         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7465
7466         # find mirrored files with specific file state
7467         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7468         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7469
7470         cmd="$LFS find --mirror-state=ro --type f $td"
7471         nfiles=$($cmd | wc -l)
7472         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7473
7474         cmd="$LFS find ! --mirror-state=ro --type f $td"
7475         nfiles=$($cmd | wc -l)
7476         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7477
7478         cmd="$LFS find --mirror-state=wp --type f $td"
7479         nfiles=$($cmd | wc -l)
7480         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7481
7482         cmd="$LFS find ! --mirror-state=sp --type f $td"
7483         nfiles=$($cmd | wc -l)
7484         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7485 }
7486 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7487
7488 test_57a() {
7489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7490         # note test will not do anything if MDS is not local
7491         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7492                 skip_env "ldiskfs only test"
7493         fi
7494         remote_mds_nodsh && skip "remote MDS with nodsh"
7495
7496         local MNTDEV="osd*.*MDT*.mntdev"
7497         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7498         [ -z "$DEV" ] && error "can't access $MNTDEV"
7499         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7500                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7501                         error "can't access $DEV"
7502                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7503                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7504                 rm $TMP/t57a.dump
7505         done
7506 }
7507 run_test 57a "verify MDS filesystem created with large inodes =="
7508
7509 test_57b() {
7510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7511         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7512                 skip_env "ldiskfs only test"
7513         fi
7514         remote_mds_nodsh && skip "remote MDS with nodsh"
7515
7516         local dir=$DIR/$tdir
7517         local filecount=100
7518         local file1=$dir/f1
7519         local fileN=$dir/f$filecount
7520
7521         rm -rf $dir || error "removing $dir"
7522         test_mkdir -c1 $dir
7523         local mdtidx=$($LFS getstripe -m $dir)
7524         local mdtname=MDT$(printf %04x $mdtidx)
7525         local facet=mds$((mdtidx + 1))
7526
7527         echo "mcreating $filecount files"
7528         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7529
7530         # verify that files do not have EAs yet
7531         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7532                 error "$file1 has an EA"
7533         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7534                 error "$fileN has an EA"
7535
7536         sync
7537         sleep 1
7538         df $dir  #make sure we get new statfs data
7539         local mdsfree=$(do_facet $facet \
7540                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7541         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7542         local file
7543
7544         echo "opening files to create objects/EAs"
7545         for file in $(seq -f $dir/f%g 1 $filecount); do
7546                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7547                         error "opening $file"
7548         done
7549
7550         # verify that files have EAs now
7551         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7552         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7553
7554         sleep 1  #make sure we get new statfs data
7555         df $dir
7556         local mdsfree2=$(do_facet $facet \
7557                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7558         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7559
7560         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7561                 if [ "$mdsfree" != "$mdsfree2" ]; then
7562                         error "MDC before $mdcfree != after $mdcfree2"
7563                 else
7564                         echo "MDC before $mdcfree != after $mdcfree2"
7565                         echo "unable to confirm if MDS has large inodes"
7566                 fi
7567         fi
7568         rm -rf $dir
7569 }
7570 run_test 57b "default LOV EAs are stored inside large inodes ==="
7571
7572 test_58() {
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574         [ -z "$(which wiretest 2>/dev/null)" ] &&
7575                         skip_env "could not find wiretest"
7576
7577         wiretest
7578 }
7579 run_test 58 "verify cross-platform wire constants =============="
7580
7581 test_59() {
7582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7583
7584         echo "touch 130 files"
7585         createmany -o $DIR/f59- 130
7586         echo "rm 130 files"
7587         unlinkmany $DIR/f59- 130
7588         sync
7589         # wait for commitment of removal
7590         wait_delete_completed
7591 }
7592 run_test 59 "verify cancellation of llog records async ========="
7593
7594 TEST60_HEAD="test_60 run $RANDOM"
7595 test_60a() {
7596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7597         remote_mgs_nodsh && skip "remote MGS with nodsh"
7598         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7599                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7600                         skip_env "missing subtest run-llog.sh"
7601
7602         log "$TEST60_HEAD - from kernel mode"
7603         do_facet mgs "$LCTL dk > /dev/null"
7604         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7605         do_facet mgs $LCTL dk > $TMP/$tfile
7606
7607         # LU-6388: test llog_reader
7608         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7609         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7610         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7611                         skip_env "missing llog_reader"
7612         local fstype=$(facet_fstype mgs)
7613         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7614                 skip_env "Only for ldiskfs or zfs type mgs"
7615
7616         local mntpt=$(facet_mntpt mgs)
7617         local mgsdev=$(mgsdevname 1)
7618         local fid_list
7619         local fid
7620         local rec_list
7621         local rec
7622         local rec_type
7623         local obj_file
7624         local path
7625         local seq
7626         local oid
7627         local pass=true
7628
7629         #get fid and record list
7630         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7631                 tail -n 4))
7632         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7633                 tail -n 4))
7634         #remount mgs as ldiskfs or zfs type
7635         stop mgs || error "stop mgs failed"
7636         mount_fstype mgs || error "remount mgs failed"
7637         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7638                 fid=${fid_list[i]}
7639                 rec=${rec_list[i]}
7640                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7641                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7642                 oid=$((16#$oid))
7643
7644                 case $fstype in
7645                         ldiskfs )
7646                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7647                         zfs )
7648                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7649                 esac
7650                 echo "obj_file is $obj_file"
7651                 do_facet mgs $llog_reader $obj_file
7652
7653                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7654                         awk '{ print $3 }' | sed -e "s/^type=//g")
7655                 if [ $rec_type != $rec ]; then
7656                         echo "FAILED test_60a wrong record type $rec_type," \
7657                               "should be $rec"
7658                         pass=false
7659                         break
7660                 fi
7661
7662                 #check obj path if record type is LLOG_LOGID_MAGIC
7663                 if [ "$rec" == "1064553b" ]; then
7664                         path=$(do_facet mgs $llog_reader $obj_file |
7665                                 grep "path=" | awk '{ print $NF }' |
7666                                 sed -e "s/^path=//g")
7667                         if [ $obj_file != $mntpt/$path ]; then
7668                                 echo "FAILED test_60a wrong obj path" \
7669                                       "$montpt/$path, should be $obj_file"
7670                                 pass=false
7671                                 break
7672                         fi
7673                 fi
7674         done
7675         rm -f $TMP/$tfile
7676         #restart mgs before "error", otherwise it will block the next test
7677         stop mgs || error "stop mgs failed"
7678         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7679         $pass || error "test failed, see FAILED test_60a messages for specifics"
7680 }
7681 run_test 60a "llog_test run from kernel module and test llog_reader"
7682
7683 test_60b() { # bug 6411
7684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7685
7686         dmesg > $DIR/$tfile
7687         LLOG_COUNT=$(do_facet mgs dmesg |
7688                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7689                           /llog_[a-z]*.c:[0-9]/ {
7690                                 if (marker)
7691                                         from_marker++
7692                                 from_begin++
7693                           }
7694                           END {
7695                                 if (marker)
7696                                         print from_marker
7697                                 else
7698                                         print from_begin
7699                           }")
7700
7701         [[ $LLOG_COUNT -gt 120 ]] &&
7702                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7703 }
7704 run_test 60b "limit repeated messages from CERROR/CWARN"
7705
7706 test_60c() {
7707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7708
7709         echo "create 5000 files"
7710         createmany -o $DIR/f60c- 5000
7711 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7712         lctl set_param fail_loc=0x80000137
7713         unlinkmany $DIR/f60c- 5000
7714         lctl set_param fail_loc=0
7715 }
7716 run_test 60c "unlink file when mds full"
7717
7718 test_60d() {
7719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7720
7721         SAVEPRINTK=$(lctl get_param -n printk)
7722         # verify "lctl mark" is even working"
7723         MESSAGE="test message ID $RANDOM $$"
7724         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7725         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7726
7727         lctl set_param printk=0 || error "set lnet.printk failed"
7728         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7729         MESSAGE="new test message ID $RANDOM $$"
7730         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7731         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7732         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7733
7734         lctl set_param -n printk="$SAVEPRINTK"
7735 }
7736 run_test 60d "test printk console message masking"
7737
7738 test_60e() {
7739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7740         remote_mds_nodsh && skip "remote MDS with nodsh"
7741
7742         touch $DIR/$tfile
7743 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7744         do_facet mds1 lctl set_param fail_loc=0x15b
7745         rm $DIR/$tfile
7746 }
7747 run_test 60e "no space while new llog is being created"
7748
7749 test_60g() {
7750         local pid
7751         local i
7752
7753         test_mkdir -c $MDSCOUNT $DIR/$tdir
7754
7755         (
7756                 local index=0
7757                 while true; do
7758                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7759                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7760                                 2>/dev/null
7761                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7762                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7763                         index=$((index + 1))
7764                 done
7765         ) &
7766
7767         pid=$!
7768
7769         for i in {0..100}; do
7770                 # define OBD_FAIL_OSD_TXN_START    0x19a
7771                 local index=$((i % MDSCOUNT + 1))
7772
7773                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7774                         > /dev/null
7775                 sleep 0.01
7776         done
7777
7778         kill -9 $pid
7779
7780         for i in $(seq $MDSCOUNT); do
7781                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7782         done
7783
7784         mkdir $DIR/$tdir/new || error "mkdir failed"
7785         rmdir $DIR/$tdir/new || error "rmdir failed"
7786
7787         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7788                 -t namespace
7789         for i in $(seq $MDSCOUNT); do
7790                 wait_update_facet mds$i "$LCTL get_param -n \
7791                         mdd.$(facet_svc mds$i).lfsck_namespace |
7792                         awk '/^status/ { print \\\$2 }'" "completed"
7793         done
7794
7795         ls -R $DIR/$tdir || error "ls failed"
7796         rm -rf $DIR/$tdir || error "rmdir failed"
7797 }
7798 run_test 60g "transaction abort won't cause MDT hung"
7799
7800 test_60h() {
7801         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7802                 skip "Need MDS version at least 2.12.52"
7803         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7804
7805         local f
7806
7807         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7808         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7809         for fail_loc in 0x80000188 0x80000189; do
7810                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7811                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7812                         error "mkdir $dir-$fail_loc failed"
7813                 for i in {0..10}; do
7814                         # create may fail on missing stripe
7815                         echo $i > $DIR/$tdir-$fail_loc/$i
7816                 done
7817                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7818                         error "getdirstripe $tdir-$fail_loc failed"
7819                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7820                         error "migrate $tdir-$fail_loc failed"
7821                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7822                         error "getdirstripe $tdir-$fail_loc failed"
7823                 pushd $DIR/$tdir-$fail_loc
7824                 for f in *; do
7825                         echo $f | cmp $f - || error "$f data mismatch"
7826                 done
7827                 popd
7828                 rm -rf $DIR/$tdir-$fail_loc
7829         done
7830 }
7831 run_test 60h "striped directory with missing stripes can be accessed"
7832
7833 test_61a() {
7834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7835
7836         f="$DIR/f61"
7837         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7838         cancel_lru_locks osc
7839         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7840         sync
7841 }
7842 run_test 61a "mmap() writes don't make sync hang ================"
7843
7844 test_61b() {
7845         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7846 }
7847 run_test 61b "mmap() of unstriped file is successful"
7848
7849 # bug 2330 - insufficient obd_match error checking causes LBUG
7850 test_62() {
7851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7852
7853         f="$DIR/f62"
7854         echo foo > $f
7855         cancel_lru_locks osc
7856         lctl set_param fail_loc=0x405
7857         cat $f && error "cat succeeded, expect -EIO"
7858         lctl set_param fail_loc=0
7859 }
7860 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7861 # match every page all of the time.
7862 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7863
7864 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7865 # Though this test is irrelevant anymore, it helped to reveal some
7866 # other grant bugs (LU-4482), let's keep it.
7867 test_63a() {   # was test_63
7868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7869
7870         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7871
7872         for i in `seq 10` ; do
7873                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7874                 sleep 5
7875                 kill $!
7876                 sleep 1
7877         done
7878
7879         rm -f $DIR/f63 || true
7880 }
7881 run_test 63a "Verify oig_wait interruption does not crash ======="
7882
7883 # bug 2248 - async write errors didn't return to application on sync
7884 # bug 3677 - async write errors left page locked
7885 test_63b() {
7886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7887
7888         debugsave
7889         lctl set_param debug=-1
7890
7891         # ensure we have a grant to do async writes
7892         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7893         rm $DIR/$tfile
7894
7895         sync    # sync lest earlier test intercept the fail_loc
7896
7897         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7898         lctl set_param fail_loc=0x80000406
7899         $MULTIOP $DIR/$tfile Owy && \
7900                 error "sync didn't return ENOMEM"
7901         sync; sleep 2; sync     # do a real sync this time to flush page
7902         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7903                 error "locked page left in cache after async error" || true
7904         debugrestore
7905 }
7906 run_test 63b "async write errors should be returned to fsync ==="
7907
7908 test_64a () {
7909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7910
7911         lfs df $DIR
7912         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7913 }
7914 run_test 64a "verify filter grant calculations (in kernel) ====="
7915
7916 test_64b () {
7917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7918
7919         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7920 }
7921 run_test 64b "check out-of-space detection on client"
7922
7923 test_64c() {
7924         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7925 }
7926 run_test 64c "verify grant shrink"
7927
7928 import_param() {
7929         local tgt=$1
7930         local param=$2
7931
7932         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7933 }
7934
7935 # this does exactly what osc_request.c:osc_announce_cached() does in
7936 # order to calculate max amount of grants to ask from server
7937 want_grant() {
7938         local tgt=$1
7939
7940         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7941         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7942
7943         ((rpc_in_flight++));
7944         nrpages=$((nrpages * rpc_in_flight))
7945
7946         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7947
7948         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7949
7950         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7951         local undirty=$((nrpages * PAGE_SIZE))
7952
7953         local max_extent_pages
7954         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7955         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7956         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7957         local grant_extent_tax
7958         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7959
7960         undirty=$((undirty + nrextents * grant_extent_tax))
7961
7962         echo $undirty
7963 }
7964
7965 # this is size of unit for grant allocation. It should be equal to
7966 # what tgt_grant.c:tgt_grant_chunk() calculates
7967 grant_chunk() {
7968         local tgt=$1
7969         local max_brw_size
7970         local grant_extent_tax
7971
7972         max_brw_size=$(import_param $tgt max_brw_size)
7973
7974         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7975
7976         echo $(((max_brw_size + grant_extent_tax) * 2))
7977 }
7978
7979 test_64d() {
7980         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7981                 skip "OST < 2.10.55 doesn't limit grants enough"
7982
7983         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7984
7985         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7986                 skip "no grant_param connect flag"
7987
7988         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7989
7990         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7991         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7992
7993
7994         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7995         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7996
7997         $LFS setstripe $DIR/$tfile -i 0 -c 1
7998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7999         ddpid=$!
8000
8001         while kill -0 $ddpid; do
8002                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8003
8004                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8005                         kill $ddpid
8006                         error "cur_grant $cur_grant > $max_cur_granted"
8007                 fi
8008
8009                 sleep 1
8010         done
8011 }
8012 run_test 64d "check grant limit exceed"
8013
8014 check_grants() {
8015         local tgt=$1
8016         local expected=$2
8017         local msg=$3
8018         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8019
8020         ((cur_grants == expected)) ||
8021                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8022 }
8023
8024 round_up_p2() {
8025         echo $((($1 + $2 - 1) & ~($2 - 1)))
8026 }
8027
8028 test_64e() {
8029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8030         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8031                 skip "Need OSS version at least 2.11.56"
8032
8033         # Remount client to reset grant
8034         remount_client $MOUNT || error "failed to remount client"
8035         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8036
8037         local init_grants=$(import_param $osc_tgt initial_grant)
8038
8039         check_grants $osc_tgt $init_grants "init grants"
8040
8041         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8042         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8043         local gbs=$(import_param $osc_tgt grant_block_size)
8044
8045         # write random number of bytes from max_brw_size / 4 to max_brw_size
8046         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8047         # align for direct io
8048         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8049         # round to grant consumption unit
8050         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8051
8052         local grants=$((wb_round_up + extent_tax))
8053
8054         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8055
8056         # define OBD_FAIL_TGT_NO_GRANT 0x725
8057         # make the server not grant more back
8058         do_facet ost1 $LCTL set_param fail_loc=0x725
8059         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8060
8061         do_facet ost1 $LCTL set_param fail_loc=0
8062
8063         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8064
8065         rm -f $DIR/$tfile || error "rm failed"
8066
8067         # Remount client to reset grant
8068         remount_client $MOUNT || error "failed to remount client"
8069         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8070
8071         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8072
8073         # define OBD_FAIL_TGT_NO_GRANT 0x725
8074         # make the server not grant more back
8075         do_facet ost1 $LCTL set_param fail_loc=0x725
8076         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8077         do_facet ost1 $LCTL set_param fail_loc=0
8078
8079         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8080 }
8081 run_test 64e "check grant consumption (no grant allocation)"
8082
8083 test_64f() {
8084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8085
8086         # Remount client to reset grant
8087         remount_client $MOUNT || error "failed to remount client"
8088         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8089
8090         local init_grants=$(import_param $osc_tgt initial_grant)
8091         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8092         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8093         local gbs=$(import_param $osc_tgt grant_block_size)
8094         local chunk=$(grant_chunk $osc_tgt)
8095
8096         # write random number of bytes from max_brw_size / 4 to max_brw_size
8097         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8098         # align for direct io
8099         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8100         # round to grant consumption unit
8101         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8102
8103         local grants=$((wb_round_up + extent_tax))
8104
8105         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8106         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8107                 error "error writing to $DIR/$tfile"
8108
8109         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8110                 "direct io with grant allocation"
8111
8112         rm -f $DIR/$tfile || error "rm failed"
8113
8114         # Remount client to reset grant
8115         remount_client $MOUNT || error "failed to remount client"
8116         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8117
8118         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8119
8120         local cmd="oO_WRONLY:w${write_bytes}_yc"
8121
8122         $MULTIOP $DIR/$tfile $cmd &
8123         MULTIPID=$!
8124         sleep 1
8125
8126         check_grants $osc_tgt $((init_grants - grants)) \
8127                 "buffered io, not write rpc"
8128
8129         kill -USR1 $MULTIPID
8130         wait
8131
8132         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8133                 "buffered io, one RPC"
8134 }
8135 run_test 64f "check grant consumption (with grant allocation)"
8136
8137 # bug 1414 - set/get directories' stripe info
8138 test_65a() {
8139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8140
8141         test_mkdir $DIR/$tdir
8142         touch $DIR/$tdir/f1
8143         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8144 }
8145 run_test 65a "directory with no stripe info"
8146
8147 test_65b() {
8148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8149
8150         test_mkdir $DIR/$tdir
8151         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8152
8153         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8154                                                 error "setstripe"
8155         touch $DIR/$tdir/f2
8156         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8157 }
8158 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8159
8160 test_65c() {
8161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8162         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8163
8164         test_mkdir $DIR/$tdir
8165         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8166
8167         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8168                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8169         touch $DIR/$tdir/f3
8170         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8171 }
8172 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8173
8174 test_65d() {
8175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8176
8177         test_mkdir $DIR/$tdir
8178         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8179         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8180
8181         if [[ $STRIPECOUNT -le 0 ]]; then
8182                 sc=1
8183         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8184                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8185                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8186         else
8187                 sc=$(($STRIPECOUNT - 1))
8188         fi
8189         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8190         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8191         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8192                 error "lverify failed"
8193 }
8194 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8195
8196 test_65e() {
8197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8198
8199         test_mkdir $DIR/$tdir
8200
8201         $LFS setstripe $DIR/$tdir || error "setstripe"
8202         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8203                                         error "no stripe info failed"
8204         touch $DIR/$tdir/f6
8205         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8206 }
8207 run_test 65e "directory setstripe defaults"
8208
8209 test_65f() {
8210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8211
8212         test_mkdir $DIR/${tdir}f
8213         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8214                 error "setstripe succeeded" || true
8215 }
8216 run_test 65f "dir setstripe permission (should return error) ==="
8217
8218 test_65g() {
8219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8220
8221         test_mkdir $DIR/$tdir
8222         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8223
8224         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8225                 error "setstripe -S failed"
8226         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8227         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8228                 error "delete default stripe failed"
8229 }
8230 run_test 65g "directory setstripe -d"
8231
8232 test_65h() {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         test_mkdir $DIR/$tdir
8236         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8237
8238         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8239                 error "setstripe -S failed"
8240         test_mkdir $DIR/$tdir/dd1
8241         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8242                 error "stripe info inherit failed"
8243 }
8244 run_test 65h "directory stripe info inherit ===================="
8245
8246 test_65i() {
8247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8248
8249         save_layout_restore_at_exit $MOUNT
8250
8251         # bug6367: set non-default striping on root directory
8252         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8253
8254         # bug12836: getstripe on -1 default directory striping
8255         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8256
8257         # bug12836: getstripe -v on -1 default directory striping
8258         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8259
8260         # bug12836: new find on -1 default directory striping
8261         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8262 }
8263 run_test 65i "various tests to set root directory striping"
8264
8265 test_65j() { # bug6367
8266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8267
8268         sync; sleep 1
8269
8270         # if we aren't already remounting for each test, do so for this test
8271         if [ "$I_MOUNTED" = "yes" ]; then
8272                 cleanup || error "failed to unmount"
8273                 setup
8274         fi
8275
8276         save_layout_restore_at_exit $MOUNT
8277
8278         $LFS setstripe -d $MOUNT || error "setstripe failed"
8279 }
8280 run_test 65j "set default striping on root directory (bug 6367)="
8281
8282 cleanup_65k() {
8283         rm -rf $DIR/$tdir
8284         wait_delete_completed
8285         do_facet $SINGLEMDS "lctl set_param -n \
8286                 osp.$ost*MDT0000.max_create_count=$max_count"
8287         do_facet $SINGLEMDS "lctl set_param -n \
8288                 osp.$ost*MDT0000.create_count=$count"
8289         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8290         echo $INACTIVE_OSC "is Activate"
8291
8292         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8293 }
8294
8295 test_65k() { # bug11679
8296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8297         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8298         remote_mds_nodsh && skip "remote MDS with nodsh"
8299
8300         local disable_precreate=true
8301         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8302                 disable_precreate=false
8303
8304         echo "Check OST status: "
8305         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8306                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8307
8308         for OSC in $MDS_OSCS; do
8309                 echo $OSC "is active"
8310                 do_facet $SINGLEMDS lctl --device %$OSC activate
8311         done
8312
8313         for INACTIVE_OSC in $MDS_OSCS; do
8314                 local ost=$(osc_to_ost $INACTIVE_OSC)
8315                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8316                                lov.*md*.target_obd |
8317                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8318
8319                 mkdir -p $DIR/$tdir
8320                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8321                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8322
8323                 echo "Deactivate: " $INACTIVE_OSC
8324                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8325
8326                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8327                               osp.$ost*MDT0000.create_count")
8328                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8329                                   osp.$ost*MDT0000.max_create_count")
8330                 $disable_precreate &&
8331                         do_facet $SINGLEMDS "lctl set_param -n \
8332                                 osp.$ost*MDT0000.max_create_count=0"
8333
8334                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8335                         [ -f $DIR/$tdir/$idx ] && continue
8336                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8337                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8338                                 { cleanup_65k;
8339                                   error "setstripe $idx should succeed"; }
8340                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8341                 done
8342                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8343                 rmdir $DIR/$tdir
8344
8345                 do_facet $SINGLEMDS "lctl set_param -n \
8346                         osp.$ost*MDT0000.max_create_count=$max_count"
8347                 do_facet $SINGLEMDS "lctl set_param -n \
8348                         osp.$ost*MDT0000.create_count=$count"
8349                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8350                 echo $INACTIVE_OSC "is Activate"
8351
8352                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8353         done
8354 }
8355 run_test 65k "validate manual striping works properly with deactivated OSCs"
8356
8357 test_65l() { # bug 12836
8358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8359
8360         test_mkdir -p $DIR/$tdir/test_dir
8361         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8362         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8363 }
8364 run_test 65l "lfs find on -1 stripe dir ========================"
8365
8366 test_65m() {
8367         local layout=$(save_layout $MOUNT)
8368         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8369                 restore_layout $MOUNT $layout
8370                 error "setstripe should fail by non-root users"
8371         }
8372         true
8373 }
8374 run_test 65m "normal user can't set filesystem default stripe"
8375
8376 test_65n() {
8377         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8378         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8379                 skip "Need MDS version at least 2.12.50"
8380         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8381
8382         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8383         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8384         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8385
8386         local root_layout=$(save_layout $MOUNT)
8387         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8388
8389         # new subdirectory under root directory should not inherit
8390         # the default layout from root
8391         local dir1=$MOUNT/$tdir-1
8392         mkdir $dir1 || error "mkdir $dir1 failed"
8393         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8394                 error "$dir1 shouldn't have LOV EA"
8395
8396         # delete the default layout on root directory
8397         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8398
8399         local dir2=$MOUNT/$tdir-2
8400         mkdir $dir2 || error "mkdir $dir2 failed"
8401         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8402                 error "$dir2 shouldn't have LOV EA"
8403
8404         # set a new striping pattern on root directory
8405         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8406         local new_def_stripe_size=$((def_stripe_size * 2))
8407         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8408                 error "set stripe size on $MOUNT failed"
8409
8410         # new file created in $dir2 should inherit the new stripe size from
8411         # the filesystem default
8412         local file2=$dir2/$tfile-2
8413         touch $file2 || error "touch $file2 failed"
8414
8415         local file2_stripe_size=$($LFS getstripe -S $file2)
8416         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8417         {
8418                 echo "file2_stripe_size: '$file2_stripe_size'"
8419                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8420                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8421         }
8422
8423         local dir3=$MOUNT/$tdir-3
8424         mkdir $dir3 || error "mkdir $dir3 failed"
8425         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8426         # the root layout, which is the actual default layout that will be used
8427         # when new files are created in $dir3.
8428         local dir3_layout=$(get_layout_param $dir3)
8429         local root_dir_layout=$(get_layout_param $MOUNT)
8430         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8431         {
8432                 echo "dir3_layout: '$dir3_layout'"
8433                 echo "root_dir_layout: '$root_dir_layout'"
8434                 error "$dir3 should show the default layout from $MOUNT"
8435         }
8436
8437         # set OST pool on root directory
8438         local pool=$TESTNAME
8439         pool_add $pool || error "add $pool failed"
8440         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8441                 error "add targets to $pool failed"
8442
8443         $LFS setstripe -p $pool $MOUNT ||
8444                 error "set OST pool on $MOUNT failed"
8445
8446         # new file created in $dir3 should inherit the pool from
8447         # the filesystem default
8448         local file3=$dir3/$tfile-3
8449         touch $file3 || error "touch $file3 failed"
8450
8451         local file3_pool=$($LFS getstripe -p $file3)
8452         [[ "$file3_pool" = "$pool" ]] ||
8453                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8454
8455         local dir4=$MOUNT/$tdir-4
8456         mkdir $dir4 || error "mkdir $dir4 failed"
8457         local dir4_layout=$(get_layout_param $dir4)
8458         root_dir_layout=$(get_layout_param $MOUNT)
8459         echo "$LFS getstripe -d $dir4"
8460         $LFS getstripe -d $dir4
8461         echo "$LFS getstripe -d $MOUNT"
8462         $LFS getstripe -d $MOUNT
8463         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8464         {
8465                 echo "dir4_layout: '$dir4_layout'"
8466                 echo "root_dir_layout: '$root_dir_layout'"
8467                 error "$dir4 should show the default layout from $MOUNT"
8468         }
8469
8470         # new file created in $dir4 should inherit the pool from
8471         # the filesystem default
8472         local file4=$dir4/$tfile-4
8473         touch $file4 || error "touch $file4 failed"
8474
8475         local file4_pool=$($LFS getstripe -p $file4)
8476         [[ "$file4_pool" = "$pool" ]] ||
8477                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8478
8479         # new subdirectory under non-root directory should inherit
8480         # the default layout from its parent directory
8481         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8482                 error "set directory layout on $dir4 failed"
8483
8484         local dir5=$dir4/$tdir-5
8485         mkdir $dir5 || error "mkdir $dir5 failed"
8486
8487         dir4_layout=$(get_layout_param $dir4)
8488         local dir5_layout=$(get_layout_param $dir5)
8489         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8490         {
8491                 echo "dir4_layout: '$dir4_layout'"
8492                 echo "dir5_layout: '$dir5_layout'"
8493                 error "$dir5 should inherit the default layout from $dir4"
8494         }
8495
8496         # though subdir under ROOT doesn't inherit default layout, but
8497         # its sub dir/file should be created with default layout.
8498         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8499         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8500                 skip "Need MDS version at least 2.12.59"
8501
8502         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8503         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8504         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8505
8506         if [ $default_lmv_hash == "none" ]; then
8507                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8508         else
8509                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8510                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8511         fi
8512
8513         $LFS setdirstripe -D -c 2 $MOUNT ||
8514                 error "setdirstripe -D -c 2 failed"
8515         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8516         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8517         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8518 }
8519 run_test 65n "don't inherit default layout from root for new subdirectories"
8520
8521 # bug 2543 - update blocks count on client
8522 test_66() {
8523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8524
8525         COUNT=${COUNT:-8}
8526         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8527         sync; sync_all_data; sync; sync_all_data
8528         cancel_lru_locks osc
8529         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8530         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8531 }
8532 run_test 66 "update inode blocks count on client ==============="
8533
8534 meminfo() {
8535         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8536 }
8537
8538 swap_used() {
8539         swapon -s | awk '($1 == "'$1'") { print $4 }'
8540 }
8541
8542 # bug5265, obdfilter oa2dentry return -ENOENT
8543 # #define OBD_FAIL_SRV_ENOENT 0x217
8544 test_69() {
8545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8546         remote_ost_nodsh && skip "remote OST with nodsh"
8547
8548         f="$DIR/$tfile"
8549         $LFS setstripe -c 1 -i 0 $f
8550
8551         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8552
8553         do_facet ost1 lctl set_param fail_loc=0x217
8554         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8555         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8556
8557         do_facet ost1 lctl set_param fail_loc=0
8558         $DIRECTIO write $f 0 2 || error "write error"
8559
8560         cancel_lru_locks osc
8561         $DIRECTIO read $f 0 1 || error "read error"
8562
8563         do_facet ost1 lctl set_param fail_loc=0x217
8564         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8565
8566         do_facet ost1 lctl set_param fail_loc=0
8567         rm -f $f
8568 }
8569 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8570
8571 test_71() {
8572         test_mkdir $DIR/$tdir
8573         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8574         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8575 }
8576 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8577
8578 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8580         [ "$RUNAS_ID" = "$UID" ] &&
8581                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8582         # Check that testing environment is properly set up. Skip if not
8583         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8584                 skip_env "User $RUNAS_ID does not exist - skipping"
8585
8586         touch $DIR/$tfile
8587         chmod 777 $DIR/$tfile
8588         chmod ug+s $DIR/$tfile
8589         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8590                 error "$RUNAS dd $DIR/$tfile failed"
8591         # See if we are still setuid/sgid
8592         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8593                 error "S/gid is not dropped on write"
8594         # Now test that MDS is updated too
8595         cancel_lru_locks mdc
8596         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8597                 error "S/gid is not dropped on MDS"
8598         rm -f $DIR/$tfile
8599 }
8600 run_test 72a "Test that remove suid works properly (bug5695) ===="
8601
8602 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8603         local perm
8604
8605         [ "$RUNAS_ID" = "$UID" ] &&
8606                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8607         [ "$RUNAS_ID" -eq 0 ] &&
8608                 skip_env "RUNAS_ID = 0 -- skipping"
8609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8610         # Check that testing environment is properly set up. Skip if not
8611         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8612                 skip_env "User $RUNAS_ID does not exist - skipping"
8613
8614         touch $DIR/${tfile}-f{g,u}
8615         test_mkdir $DIR/${tfile}-dg
8616         test_mkdir $DIR/${tfile}-du
8617         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8618         chmod g+s $DIR/${tfile}-{f,d}g
8619         chmod u+s $DIR/${tfile}-{f,d}u
8620         for perm in 777 2777 4777; do
8621                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8622                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8623                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8624                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8625         done
8626         true
8627 }
8628 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8629
8630 # bug 3462 - multiple simultaneous MDC requests
8631 test_73() {
8632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8633
8634         test_mkdir $DIR/d73-1
8635         test_mkdir $DIR/d73-2
8636         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8637         pid1=$!
8638
8639         lctl set_param fail_loc=0x80000129
8640         $MULTIOP $DIR/d73-1/f73-2 Oc &
8641         sleep 1
8642         lctl set_param fail_loc=0
8643
8644         $MULTIOP $DIR/d73-2/f73-3 Oc &
8645         pid3=$!
8646
8647         kill -USR1 $pid1
8648         wait $pid1 || return 1
8649
8650         sleep 25
8651
8652         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8653         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8654         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8655
8656         rm -rf $DIR/d73-*
8657 }
8658 run_test 73 "multiple MDC requests (should not deadlock)"
8659
8660 test_74a() { # bug 6149, 6184
8661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8662
8663         touch $DIR/f74a
8664         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8665         #
8666         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8667         # will spin in a tight reconnection loop
8668         $LCTL set_param fail_loc=0x8000030e
8669         # get any lock that won't be difficult - lookup works.
8670         ls $DIR/f74a
8671         $LCTL set_param fail_loc=0
8672         rm -f $DIR/f74a
8673         true
8674 }
8675 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8676
8677 test_74b() { # bug 13310
8678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8679
8680         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8681         #
8682         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8683         # will spin in a tight reconnection loop
8684         $LCTL set_param fail_loc=0x8000030e
8685         # get a "difficult" lock
8686         touch $DIR/f74b
8687         $LCTL set_param fail_loc=0
8688         rm -f $DIR/f74b
8689         true
8690 }
8691 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8692
8693 test_74c() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695
8696         #define OBD_FAIL_LDLM_NEW_LOCK
8697         $LCTL set_param fail_loc=0x319
8698         touch $DIR/$tfile && error "touch successful"
8699         $LCTL set_param fail_loc=0
8700         true
8701 }
8702 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8703
8704 slab_lic=/sys/kernel/slab/lustre_inode_cache
8705 num_objects() {
8706         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8707         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8708                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8709 }
8710
8711 test_76a() { # Now for b=20433, added originally in b=1443
8712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8713
8714         cancel_lru_locks osc
8715         # there may be some slab objects cached per core
8716         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8717         local before=$(num_objects)
8718         local count=$((512 * cpus))
8719         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8720         local margin=$((count / 10))
8721         if [[ -f $slab_lic/aliases ]]; then
8722                 local aliases=$(cat $slab_lic/aliases)
8723                 (( aliases > 0 )) && margin=$((margin * aliases))
8724         fi
8725
8726         echo "before slab objects: $before"
8727         for i in $(seq $count); do
8728                 touch $DIR/$tfile
8729                 rm -f $DIR/$tfile
8730         done
8731         cancel_lru_locks osc
8732         local after=$(num_objects)
8733         echo "created: $count, after slab objects: $after"
8734         # shared slab counts are not very accurate, allow significant margin
8735         # the main goal is that the cache growth is not permanently > $count
8736         while (( after > before + margin )); do
8737                 sleep 1
8738                 after=$(num_objects)
8739                 wait=$((wait + 1))
8740                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8741                 if (( wait > 60 )); then
8742                         error "inode slab grew from $before+$margin to $after"
8743                 fi
8744         done
8745 }
8746 run_test 76a "confirm clients recycle inodes properly ===="
8747
8748 test_76b() {
8749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8750         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8751
8752         local count=512
8753         local before=$(num_objects)
8754
8755         for i in $(seq $count); do
8756                 mkdir $DIR/$tdir
8757                 rmdir $DIR/$tdir
8758         done
8759
8760         local after=$(num_objects)
8761         local wait=0
8762
8763         while (( after > before )); do
8764                 sleep 1
8765                 after=$(num_objects)
8766                 wait=$((wait + 1))
8767                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8768                 if (( wait > 60 )); then
8769                         error "inode slab grew from $before to $after"
8770                 fi
8771         done
8772
8773         echo "slab objects before: $before, after: $after"
8774 }
8775 run_test 76b "confirm clients recycle directory inodes properly ===="
8776
8777 export ORIG_CSUM=""
8778 set_checksums()
8779 {
8780         # Note: in sptlrpc modes which enable its own bulk checksum, the
8781         # original crc32_le bulk checksum will be automatically disabled,
8782         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8783         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8784         # In this case set_checksums() will not be no-op, because sptlrpc
8785         # bulk checksum will be enabled all through the test.
8786
8787         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8788         lctl set_param -n osc.*.checksums $1
8789         return 0
8790 }
8791
8792 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8793                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8794 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8795                              tr -d [] | head -n1)}
8796 set_checksum_type()
8797 {
8798         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8799         rc=$?
8800         log "set checksum type to $1, rc = $rc"
8801         return $rc
8802 }
8803
8804 get_osc_checksum_type()
8805 {
8806         # arugment 1: OST name, like OST0000
8807         ost=$1
8808         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8809                         sed 's/.*\[\(.*\)\].*/\1/g')
8810         rc=$?
8811         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8812         echo $checksum_type
8813 }
8814
8815 F77_TMP=$TMP/f77-temp
8816 F77SZ=8
8817 setup_f77() {
8818         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8819                 error "error writing to $F77_TMP"
8820 }
8821
8822 test_77a() { # bug 10889
8823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8824         $GSS && skip_env "could not run with gss"
8825
8826         [ ! -f $F77_TMP ] && setup_f77
8827         set_checksums 1
8828         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8829         set_checksums 0
8830         rm -f $DIR/$tfile
8831 }
8832 run_test 77a "normal checksum read/write operation"
8833
8834 test_77b() { # bug 10889
8835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8836         $GSS && skip_env "could not run with gss"
8837
8838         [ ! -f $F77_TMP ] && setup_f77
8839         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8840         $LCTL set_param fail_loc=0x80000409
8841         set_checksums 1
8842
8843         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8844                 error "dd error: $?"
8845         $LCTL set_param fail_loc=0
8846
8847         for algo in $CKSUM_TYPES; do
8848                 cancel_lru_locks osc
8849                 set_checksum_type $algo
8850                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8851                 $LCTL set_param fail_loc=0x80000408
8852                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8853                 $LCTL set_param fail_loc=0
8854         done
8855         set_checksums 0
8856         set_checksum_type $ORIG_CSUM_TYPE
8857         rm -f $DIR/$tfile
8858 }
8859 run_test 77b "checksum error on client write, read"
8860
8861 cleanup_77c() {
8862         trap 0
8863         set_checksums 0
8864         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8865         $check_ost &&
8866                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8867         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8868         $check_ost && [ -n "$ost_file_prefix" ] &&
8869                 do_facet ost1 rm -f ${ost_file_prefix}\*
8870 }
8871
8872 test_77c() {
8873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8874         $GSS && skip_env "could not run with gss"
8875         remote_ost_nodsh && skip "remote OST with nodsh"
8876
8877         local bad1
8878         local osc_file_prefix
8879         local osc_file
8880         local check_ost=false
8881         local ost_file_prefix
8882         local ost_file
8883         local orig_cksum
8884         local dump_cksum
8885         local fid
8886
8887         # ensure corruption will occur on first OSS/OST
8888         $LFS setstripe -i 0 $DIR/$tfile
8889
8890         [ ! -f $F77_TMP ] && setup_f77
8891         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8892                 error "dd write error: $?"
8893         fid=$($LFS path2fid $DIR/$tfile)
8894
8895         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8896         then
8897                 check_ost=true
8898                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8899                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8900         else
8901                 echo "OSS do not support bulk pages dump upon error"
8902         fi
8903
8904         osc_file_prefix=$($LCTL get_param -n debug_path)
8905         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8906
8907         trap cleanup_77c EXIT
8908
8909         set_checksums 1
8910         # enable bulk pages dump upon error on Client
8911         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8912         # enable bulk pages dump upon error on OSS
8913         $check_ost &&
8914                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8915
8916         # flush Client cache to allow next read to reach OSS
8917         cancel_lru_locks osc
8918
8919         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8920         $LCTL set_param fail_loc=0x80000408
8921         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8922         $LCTL set_param fail_loc=0
8923
8924         rm -f $DIR/$tfile
8925
8926         # check cksum dump on Client
8927         osc_file=$(ls ${osc_file_prefix}*)
8928         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8929         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8930         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8931         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8932         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8933                      cksum)
8934         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8935         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8936                 error "dump content does not match on Client"
8937
8938         $check_ost || skip "No need to check cksum dump on OSS"
8939
8940         # check cksum dump on OSS
8941         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8942         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8943         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8944         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8945         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8946                 error "dump content does not match on OSS"
8947
8948         cleanup_77c
8949 }
8950 run_test 77c "checksum error on client read with debug"
8951
8952 test_77d() { # bug 10889
8953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8954         $GSS && skip_env "could not run with gss"
8955
8956         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8957         $LCTL set_param fail_loc=0x80000409
8958         set_checksums 1
8959         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8960                 error "direct write: rc=$?"
8961         $LCTL set_param fail_loc=0
8962         set_checksums 0
8963
8964         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8965         $LCTL set_param fail_loc=0x80000408
8966         set_checksums 1
8967         cancel_lru_locks osc
8968         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8969                 error "direct read: rc=$?"
8970         $LCTL set_param fail_loc=0
8971         set_checksums 0
8972 }
8973 run_test 77d "checksum error on OST direct write, read"
8974
8975 test_77f() { # bug 10889
8976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8977         $GSS && skip_env "could not run with gss"
8978
8979         set_checksums 1
8980         for algo in $CKSUM_TYPES; do
8981                 cancel_lru_locks osc
8982                 set_checksum_type $algo
8983                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8984                 $LCTL set_param fail_loc=0x409
8985                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8986                         error "direct write succeeded"
8987                 $LCTL set_param fail_loc=0
8988         done
8989         set_checksum_type $ORIG_CSUM_TYPE
8990         set_checksums 0
8991 }
8992 run_test 77f "repeat checksum error on write (expect error)"
8993
8994 test_77g() { # bug 10889
8995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8996         $GSS && skip_env "could not run with gss"
8997         remote_ost_nodsh && skip "remote OST with nodsh"
8998
8999         [ ! -f $F77_TMP ] && setup_f77
9000
9001         local file=$DIR/$tfile
9002         stack_trap "rm -f $file" EXIT
9003
9004         $LFS setstripe -c 1 -i 0 $file
9005         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9006         do_facet ost1 lctl set_param fail_loc=0x8000021a
9007         set_checksums 1
9008         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9009                 error "write error: rc=$?"
9010         do_facet ost1 lctl set_param fail_loc=0
9011         set_checksums 0
9012
9013         cancel_lru_locks osc
9014         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9015         do_facet ost1 lctl set_param fail_loc=0x8000021b
9016         set_checksums 1
9017         cmp $F77_TMP $file || error "file compare failed"
9018         do_facet ost1 lctl set_param fail_loc=0
9019         set_checksums 0
9020 }
9021 run_test 77g "checksum error on OST write, read"
9022
9023 test_77k() { # LU-10906
9024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9025         $GSS && skip_env "could not run with gss"
9026
9027         local cksum_param="osc.$FSNAME*.checksums"
9028         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9029         local checksum
9030         local i
9031
9032         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9033         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9034         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9035
9036         for i in 0 1; do
9037                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9038                         error "failed to set checksum=$i on MGS"
9039                 wait_update $HOSTNAME "$get_checksum" $i
9040                 #remount
9041                 echo "remount client, checksum should be $i"
9042                 remount_client $MOUNT || error "failed to remount client"
9043                 checksum=$(eval $get_checksum)
9044                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9045         done
9046         # remove persistent param to avoid races with checksum mountopt below
9047         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9048                 error "failed to delete checksum on MGS"
9049
9050         for opt in "checksum" "nochecksum"; do
9051                 #remount with mount option
9052                 echo "remount client with option $opt, checksum should be $i"
9053                 umount_client $MOUNT || error "failed to umount client"
9054                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9055                         error "failed to mount client with option '$opt'"
9056                 checksum=$(eval $get_checksum)
9057                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9058                 i=$((i - 1))
9059         done
9060
9061         remount_client $MOUNT || error "failed to remount client"
9062 }
9063 run_test 77k "enable/disable checksum correctly"
9064
9065 test_77l() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         $GSS && skip_env "could not run with gss"
9068
9069         set_checksums 1
9070         stack_trap "set_checksums $ORIG_CSUM" EXIT
9071         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9072
9073         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9074
9075         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9076         for algo in $CKSUM_TYPES; do
9077                 set_checksum_type $algo || error "fail to set checksum type $algo"
9078                 osc_algo=$(get_osc_checksum_type OST0000)
9079                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9080
9081                 # no locks, no reqs to let the connection idle
9082                 cancel_lru_locks osc
9083                 lru_resize_disable osc
9084                 wait_osc_import_state client ost1 IDLE
9085
9086                 # ensure ost1 is connected
9087                 stat $DIR/$tfile >/dev/null || error "can't stat"
9088                 wait_osc_import_state client ost1 FULL
9089
9090                 osc_algo=$(get_osc_checksum_type OST0000)
9091                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9092         done
9093         return 0
9094 }
9095 run_test 77l "preferred checksum type is remembered after reconnected"
9096
9097 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9098 rm -f $F77_TMP
9099 unset F77_TMP
9100
9101 cleanup_test_78() {
9102         trap 0
9103         rm -f $DIR/$tfile
9104 }
9105
9106 test_78() { # bug 10901
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108         remote_ost || skip_env "local OST"
9109
9110         NSEQ=5
9111         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9112         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9113         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9114         echo "MemTotal: $MEMTOTAL"
9115
9116         # reserve 256MB of memory for the kernel and other running processes,
9117         # and then take 1/2 of the remaining memory for the read/write buffers.
9118         if [ $MEMTOTAL -gt 512 ] ;then
9119                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9120         else
9121                 # for those poor memory-starved high-end clusters...
9122                 MEMTOTAL=$((MEMTOTAL / 2))
9123         fi
9124         echo "Mem to use for directio: $MEMTOTAL"
9125
9126         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9127         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9128         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9129         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9130                 head -n1)
9131         echo "Smallest OST: $SMALLESTOST"
9132         [[ $SMALLESTOST -lt 10240 ]] &&
9133                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9134
9135         trap cleanup_test_78 EXIT
9136
9137         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9138                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9139
9140         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9141         echo "File size: $F78SIZE"
9142         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9143         for i in $(seq 1 $NSEQ); do
9144                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9145                 echo directIO rdwr round $i of $NSEQ
9146                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9147         done
9148
9149         cleanup_test_78
9150 }
9151 run_test 78 "handle large O_DIRECT writes correctly ============"
9152
9153 test_79() { # bug 12743
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         wait_delete_completed
9157
9158         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9159         BKFREE=$(calc_osc_kbytes kbytesfree)
9160         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9161
9162         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9163         DFTOTAL=`echo $STRING | cut -d, -f1`
9164         DFUSED=`echo $STRING  | cut -d, -f2`
9165         DFAVAIL=`echo $STRING | cut -d, -f3`
9166         DFFREE=$(($DFTOTAL - $DFUSED))
9167
9168         ALLOWANCE=$((64 * $OSTCOUNT))
9169
9170         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9171            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9172                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9173         fi
9174         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9175            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9176                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9177         fi
9178         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9179            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9180                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9181         fi
9182 }
9183 run_test 79 "df report consistency check ======================="
9184
9185 test_80() { # bug 10718
9186         remote_ost_nodsh && skip "remote OST with nodsh"
9187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9188
9189         # relax strong synchronous semantics for slow backends like ZFS
9190         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9191                 local soc="obdfilter.*.sync_lock_cancel"
9192                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9193
9194                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9195                 if [ -z "$save" ]; then
9196                         soc="obdfilter.*.sync_on_lock_cancel"
9197                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9198                 fi
9199
9200                 if [ "$save" != "never" ]; then
9201                         local hosts=$(comma_list $(osts_nodes))
9202
9203                         do_nodes $hosts $LCTL set_param $soc=never
9204                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9205                 fi
9206         fi
9207
9208         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9209         sync; sleep 1; sync
9210         local before=$(date +%s)
9211         cancel_lru_locks osc
9212         local after=$(date +%s)
9213         local diff=$((after - before))
9214         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9215
9216         rm -f $DIR/$tfile
9217 }
9218 run_test 80 "Page eviction is equally fast at high offsets too"
9219
9220 test_81a() { # LU-456
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222         remote_ost_nodsh && skip "remote OST with nodsh"
9223
9224         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9225         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9226         do_facet ost1 lctl set_param fail_loc=0x80000228
9227
9228         # write should trigger a retry and success
9229         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9230         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9231         RC=$?
9232         if [ $RC -ne 0 ] ; then
9233                 error "write should success, but failed for $RC"
9234         fi
9235 }
9236 run_test 81a "OST should retry write when get -ENOSPC ==============="
9237
9238 test_81b() { # LU-456
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240         remote_ost_nodsh && skip "remote OST with nodsh"
9241
9242         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9243         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9244         do_facet ost1 lctl set_param fail_loc=0x228
9245
9246         # write should retry several times and return -ENOSPC finally
9247         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9248         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9249         RC=$?
9250         ENOSPC=28
9251         if [ $RC -ne $ENOSPC ] ; then
9252                 error "dd should fail for -ENOSPC, but succeed."
9253         fi
9254 }
9255 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9256
9257 test_99() {
9258         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9259
9260         test_mkdir $DIR/$tdir.cvsroot
9261         chown $RUNAS_ID $DIR/$tdir.cvsroot
9262
9263         cd $TMP
9264         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9265
9266         cd /etc/init.d
9267         # some versions of cvs import exit(1) when asked to import links or
9268         # files they can't read.  ignore those files.
9269         local toignore=$(find . -type l -printf '-I %f\n' -o \
9270                          ! -perm /4 -printf '-I %f\n')
9271         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9272                 $tdir.reposname vtag rtag
9273
9274         cd $DIR
9275         test_mkdir $DIR/$tdir.reposname
9276         chown $RUNAS_ID $DIR/$tdir.reposname
9277         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9278
9279         cd $DIR/$tdir.reposname
9280         $RUNAS touch foo99
9281         $RUNAS cvs add -m 'addmsg' foo99
9282         $RUNAS cvs update
9283         $RUNAS cvs commit -m 'nomsg' foo99
9284         rm -fr $DIR/$tdir.cvsroot
9285 }
9286 run_test 99 "cvs strange file/directory operations"
9287
9288 test_100() {
9289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9290         [[ "$NETTYPE" =~ tcp ]] ||
9291                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9292         remote_ost_nodsh && skip "remote OST with nodsh"
9293         remote_mds_nodsh && skip "remote MDS with nodsh"
9294         remote_servers ||
9295                 skip "useless for local single node setup"
9296
9297         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9298                 [ "$PROT" != "tcp" ] && continue
9299                 RPORT=$(echo $REMOTE | cut -d: -f2)
9300                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9301
9302                 rc=0
9303                 LPORT=`echo $LOCAL | cut -d: -f2`
9304                 if [ $LPORT -ge 1024 ]; then
9305                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9306                         netstat -tna
9307                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9308                 fi
9309         done
9310         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9311 }
9312 run_test 100 "check local port using privileged port ==========="
9313
9314 function get_named_value()
9315 {
9316     local tag
9317
9318     tag=$1
9319     while read ;do
9320         line=$REPLY
9321         case $line in
9322         $tag*)
9323             echo $line | sed "s/^$tag[ ]*//"
9324             break
9325             ;;
9326         esac
9327     done
9328 }
9329
9330 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9331                    awk '/^max_cached_mb/ { print $2 }')
9332
9333 cleanup_101a() {
9334         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9335         trap 0
9336 }
9337
9338 test_101a() {
9339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9340
9341         local s
9342         local discard
9343         local nreads=10000
9344         local cache_limit=32
9345
9346         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9347         trap cleanup_101a EXIT
9348         $LCTL set_param -n llite.*.read_ahead_stats 0
9349         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9350
9351         #
9352         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9353         #
9354         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9355         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9356
9357         discard=0
9358         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9359                 get_named_value 'read but discarded' | cut -d" " -f1); do
9360                         discard=$(($discard + $s))
9361         done
9362         cleanup_101a
9363
9364         $LCTL get_param osc.*-osc*.rpc_stats
9365         $LCTL get_param llite.*.read_ahead_stats
9366
9367         # Discard is generally zero, but sometimes a few random reads line up
9368         # and trigger larger readahead, which is wasted & leads to discards.
9369         if [[ $(($discard)) -gt $nreads ]]; then
9370                 error "too many ($discard) discarded pages"
9371         fi
9372         rm -f $DIR/$tfile || true
9373 }
9374 run_test 101a "check read-ahead for random reads"
9375
9376 setup_test101bc() {
9377         test_mkdir $DIR/$tdir
9378         local ssize=$1
9379         local FILE_LENGTH=$2
9380         STRIPE_OFFSET=0
9381
9382         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9383
9384         local list=$(comma_list $(osts_nodes))
9385         set_osd_param $list '' read_cache_enable 0
9386         set_osd_param $list '' writethrough_cache_enable 0
9387
9388         trap cleanup_test101bc EXIT
9389         # prepare the read-ahead file
9390         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9391
9392         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9393                                 count=$FILE_SIZE_MB 2> /dev/null
9394
9395 }
9396
9397 cleanup_test101bc() {
9398         trap 0
9399         rm -rf $DIR/$tdir
9400         rm -f $DIR/$tfile
9401
9402         local list=$(comma_list $(osts_nodes))
9403         set_osd_param $list '' read_cache_enable 1
9404         set_osd_param $list '' writethrough_cache_enable 1
9405 }
9406
9407 calc_total() {
9408         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9409 }
9410
9411 ra_check_101() {
9412         local READ_SIZE=$1
9413         local STRIPE_SIZE=$2
9414         local FILE_LENGTH=$3
9415         local RA_INC=1048576
9416         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9417         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9418                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9419         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9420                         get_named_value 'read but discarded' |
9421                         cut -d" " -f1 | calc_total)
9422         if [[ $DISCARD -gt $discard_limit ]]; then
9423                 $LCTL get_param llite.*.read_ahead_stats
9424                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9425         else
9426                 echo "Read-ahead success for size ${READ_SIZE}"
9427         fi
9428 }
9429
9430 test_101b() {
9431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9432         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9433
9434         local STRIPE_SIZE=1048576
9435         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9436
9437         if [ $SLOW == "yes" ]; then
9438                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9439         else
9440                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9441         fi
9442
9443         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9444
9445         # prepare the read-ahead file
9446         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9447         cancel_lru_locks osc
9448         for BIDX in 2 4 8 16 32 64 128 256
9449         do
9450                 local BSIZE=$((BIDX*4096))
9451                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9452                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9453                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9454                 $LCTL set_param -n llite.*.read_ahead_stats 0
9455                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9456                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9457                 cancel_lru_locks osc
9458                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9459         done
9460         cleanup_test101bc
9461         true
9462 }
9463 run_test 101b "check stride-io mode read-ahead ================="
9464
9465 test_101c() {
9466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9467
9468         local STRIPE_SIZE=1048576
9469         local FILE_LENGTH=$((STRIPE_SIZE*100))
9470         local nreads=10000
9471         local rsize=65536
9472         local osc_rpc_stats
9473
9474         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9475
9476         cancel_lru_locks osc
9477         $LCTL set_param osc.*.rpc_stats 0
9478         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9479         $LCTL get_param osc.*.rpc_stats
9480         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9481                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9482                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9483                 local size
9484
9485                 if [ $lines -le 20 ]; then
9486                         echo "continue debug"
9487                         continue
9488                 fi
9489                 for size in 1 2 4 8; do
9490                         local rpc=$(echo "$stats" |
9491                                     awk '($1 == "'$size':") {print $2; exit; }')
9492                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9493                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9494                 done
9495                 echo "$osc_rpc_stats check passed!"
9496         done
9497         cleanup_test101bc
9498         true
9499 }
9500 run_test 101c "check stripe_size aligned read-ahead ================="
9501
9502 test_101d() {
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         local file=$DIR/$tfile
9506         local sz_MB=${FILESIZE_101d:-80}
9507         local ra_MB=${READAHEAD_MB:-40}
9508
9509         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9510         [ $free_MB -lt $sz_MB ] &&
9511                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9512
9513         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9514         $LFS setstripe -c -1 $file || error "setstripe failed"
9515
9516         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9517         echo Cancel LRU locks on lustre client to flush the client cache
9518         cancel_lru_locks osc
9519
9520         echo Disable read-ahead
9521         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9522         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9523         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9524         $LCTL get_param -n llite.*.max_read_ahead_mb
9525
9526         echo "Reading the test file $file with read-ahead disabled"
9527         local sz_KB=$((sz_MB * 1024 / 4))
9528         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9529         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9530         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9531                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9532
9533         echo "Cancel LRU locks on lustre client to flush the client cache"
9534         cancel_lru_locks osc
9535         echo Enable read-ahead with ${ra_MB}MB
9536         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9537
9538         echo "Reading the test file $file with read-ahead enabled"
9539         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9540                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9541
9542         echo "read-ahead disabled time read $raOFF"
9543         echo "read-ahead enabled time read $raON"
9544
9545         rm -f $file
9546         wait_delete_completed
9547
9548         # use awk for this check instead of bash because it handles decimals
9549         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9550                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9551 }
9552 run_test 101d "file read with and without read-ahead enabled"
9553
9554 test_101e() {
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556
9557         local file=$DIR/$tfile
9558         local size_KB=500  #KB
9559         local count=100
9560         local bsize=1024
9561
9562         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9563         local need_KB=$((count * size_KB))
9564         [[ $free_KB -le $need_KB ]] &&
9565                 skip_env "Need free space $need_KB, have $free_KB"
9566
9567         echo "Creating $count ${size_KB}K test files"
9568         for ((i = 0; i < $count; i++)); do
9569                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9570         done
9571
9572         echo "Cancel LRU locks on lustre client to flush the client cache"
9573         cancel_lru_locks $OSC
9574
9575         echo "Reset readahead stats"
9576         $LCTL set_param -n llite.*.read_ahead_stats 0
9577
9578         for ((i = 0; i < $count; i++)); do
9579                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9580         done
9581
9582         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9583                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9584
9585         for ((i = 0; i < $count; i++)); do
9586                 rm -rf $file.$i 2>/dev/null
9587         done
9588
9589         #10000 means 20% reads are missing in readahead
9590         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9591 }
9592 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9593
9594 test_101f() {
9595         which iozone || skip_env "no iozone installed"
9596
9597         local old_debug=$($LCTL get_param debug)
9598         old_debug=${old_debug#*=}
9599         $LCTL set_param debug="reada mmap"
9600
9601         # create a test file
9602         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9603
9604         echo Cancel LRU locks on lustre client to flush the client cache
9605         cancel_lru_locks osc
9606
9607         echo Reset readahead stats
9608         $LCTL set_param -n llite.*.read_ahead_stats 0
9609
9610         echo mmap read the file with small block size
9611         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9612                 > /dev/null 2>&1
9613
9614         echo checking missing pages
9615         $LCTL get_param llite.*.read_ahead_stats
9616         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9617                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9618
9619         $LCTL set_param debug="$old_debug"
9620         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9621         rm -f $DIR/$tfile
9622 }
9623 run_test 101f "check mmap read performance"
9624
9625 test_101g_brw_size_test() {
9626         local mb=$1
9627         local pages=$((mb * 1048576 / PAGE_SIZE))
9628         local file=$DIR/$tfile
9629
9630         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9631                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9632         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9633                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9634                         return 2
9635         done
9636
9637         stack_trap "rm -f $file" EXIT
9638         $LCTL set_param -n osc.*.rpc_stats=0
9639
9640         # 10 RPCs should be enough for the test
9641         local count=10
9642         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9643                 { error "dd write ${mb} MB blocks failed"; return 3; }
9644         cancel_lru_locks osc
9645         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9646                 { error "dd write ${mb} MB blocks failed"; return 4; }
9647
9648         # calculate number of full-sized read and write RPCs
9649         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9650                 sed -n '/pages per rpc/,/^$/p' |
9651                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9652                 END { print reads,writes }'))
9653         # allow one extra full-sized read RPC for async readahead
9654         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9655                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9656         [[ ${rpcs[1]} == $count ]] ||
9657                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9658 }
9659
9660 test_101g() {
9661         remote_ost_nodsh && skip "remote OST with nodsh"
9662
9663         local rpcs
9664         local osts=$(get_facets OST)
9665         local list=$(comma_list $(osts_nodes))
9666         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9667         local brw_size="obdfilter.*.brw_size"
9668
9669         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9670
9671         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9672
9673         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9674                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9675                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9676            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9677                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9678                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9679
9680                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9681                         suffix="M"
9682
9683                 if [[ $orig_mb -lt 16 ]]; then
9684                         save_lustre_params $osts "$brw_size" > $p
9685                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9686                                 error "set 16MB RPC size failed"
9687
9688                         echo "remount client to enable new RPC size"
9689                         remount_client $MOUNT || error "remount_client failed"
9690                 fi
9691
9692                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9693                 # should be able to set brw_size=12, but no rpc_stats for that
9694                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9695         fi
9696
9697         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9698
9699         if [[ $orig_mb -lt 16 ]]; then
9700                 restore_lustre_params < $p
9701                 remount_client $MOUNT || error "remount_client restore failed"
9702         fi
9703
9704         rm -f $p $DIR/$tfile
9705 }
9706 run_test 101g "Big bulk(4/16 MiB) readahead"
9707
9708 test_101h() {
9709         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9710
9711         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9712                 error "dd 70M file failed"
9713         echo Cancel LRU locks on lustre client to flush the client cache
9714         cancel_lru_locks osc
9715
9716         echo "Reset readahead stats"
9717         $LCTL set_param -n llite.*.read_ahead_stats 0
9718
9719         echo "Read 10M of data but cross 64M bundary"
9720         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9721         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9722                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9723         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9724         rm -f $p $DIR/$tfile
9725 }
9726 run_test 101h "Readahead should cover current read window"
9727
9728 test_101i() {
9729         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9730                 error "dd 10M file failed"
9731
9732         local max_per_file_mb=$($LCTL get_param -n \
9733                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9734         cancel_lru_locks osc
9735         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9736         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9737                 error "set max_read_ahead_per_file_mb to 1 failed"
9738
9739         echo "Reset readahead stats"
9740         $LCTL set_param llite.*.read_ahead_stats=0
9741
9742         dd if=$DIR/$tfile of=/dev/null bs=2M
9743
9744         $LCTL get_param llite.*.read_ahead_stats
9745         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9746                      awk '/misses/ { print $2 }')
9747         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9748         rm -f $DIR/$tfile
9749 }
9750 run_test 101i "allow current readahead to exceed reservation"
9751
9752 test_101j() {
9753         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9754                 error "setstripe $DIR/$tfile failed"
9755         local file_size=$((1048576 * 16))
9756         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9757         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9758
9759         echo Disable read-ahead
9760         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9761
9762         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9763         for blk in $PAGE_SIZE 1048576 $file_size; do
9764                 cancel_lru_locks osc
9765                 echo "Reset readahead stats"
9766                 $LCTL set_param -n llite.*.read_ahead_stats=0
9767                 local count=$(($file_size / $blk))
9768                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9769                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9770                              get_named_value 'failed to fast read' |
9771                              cut -d" " -f1 | calc_total)
9772                 $LCTL get_param -n llite.*.read_ahead_stats
9773                 [ $miss -eq $count ] || error "expected $count got $miss"
9774         done
9775
9776         rm -f $p $DIR/$tfile
9777 }
9778 run_test 101j "A complete read block should be submitted when no RA"
9779
9780 setup_test102() {
9781         test_mkdir $DIR/$tdir
9782         chown $RUNAS_ID $DIR/$tdir
9783         STRIPE_SIZE=65536
9784         STRIPE_OFFSET=1
9785         STRIPE_COUNT=$OSTCOUNT
9786         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9787
9788         trap cleanup_test102 EXIT
9789         cd $DIR
9790         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9791         cd $DIR/$tdir
9792         for num in 1 2 3 4; do
9793                 for count in $(seq 1 $STRIPE_COUNT); do
9794                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9795                                 local size=`expr $STRIPE_SIZE \* $num`
9796                                 local file=file"$num-$idx-$count"
9797                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9798                         done
9799                 done
9800         done
9801
9802         cd $DIR
9803         $1 tar cf $TMP/f102.tar $tdir --xattrs
9804 }
9805
9806 cleanup_test102() {
9807         trap 0
9808         rm -f $TMP/f102.tar
9809         rm -rf $DIR/d0.sanity/d102
9810 }
9811
9812 test_102a() {
9813         [ "$UID" != 0 ] && skip "must run as root"
9814         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9815                 skip_env "must have user_xattr"
9816
9817         [ -z "$(which setfattr 2>/dev/null)" ] &&
9818                 skip_env "could not find setfattr"
9819
9820         local testfile=$DIR/$tfile
9821
9822         touch $testfile
9823         echo "set/get xattr..."
9824         setfattr -n trusted.name1 -v value1 $testfile ||
9825                 error "setfattr -n trusted.name1=value1 $testfile failed"
9826         getfattr -n trusted.name1 $testfile 2> /dev/null |
9827           grep "trusted.name1=.value1" ||
9828                 error "$testfile missing trusted.name1=value1"
9829
9830         setfattr -n user.author1 -v author1 $testfile ||
9831                 error "setfattr -n user.author1=author1 $testfile failed"
9832         getfattr -n user.author1 $testfile 2> /dev/null |
9833           grep "user.author1=.author1" ||
9834                 error "$testfile missing trusted.author1=author1"
9835
9836         echo "listxattr..."
9837         setfattr -n trusted.name2 -v value2 $testfile ||
9838                 error "$testfile unable to set trusted.name2"
9839         setfattr -n trusted.name3 -v value3 $testfile ||
9840                 error "$testfile unable to set trusted.name3"
9841         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9842             grep "trusted.name" | wc -l) -eq 3 ] ||
9843                 error "$testfile missing 3 trusted.name xattrs"
9844
9845         setfattr -n user.author2 -v author2 $testfile ||
9846                 error "$testfile unable to set user.author2"
9847         setfattr -n user.author3 -v author3 $testfile ||
9848                 error "$testfile unable to set user.author3"
9849         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9850             grep "user.author" | wc -l) -eq 3 ] ||
9851                 error "$testfile missing 3 user.author xattrs"
9852
9853         echo "remove xattr..."
9854         setfattr -x trusted.name1 $testfile ||
9855                 error "$testfile error deleting trusted.name1"
9856         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9857                 error "$testfile did not delete trusted.name1 xattr"
9858
9859         setfattr -x user.author1 $testfile ||
9860                 error "$testfile error deleting user.author1"
9861         echo "set lustre special xattr ..."
9862         $LFS setstripe -c1 $testfile
9863         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9864                 awk -F "=" '/trusted.lov/ { print $2 }' )
9865         setfattr -n "trusted.lov" -v $lovea $testfile ||
9866                 error "$testfile doesn't ignore setting trusted.lov again"
9867         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9868                 error "$testfile allow setting invalid trusted.lov"
9869         rm -f $testfile
9870 }
9871 run_test 102a "user xattr test =================================="
9872
9873 check_102b_layout() {
9874         local layout="$*"
9875         local testfile=$DIR/$tfile
9876
9877         echo "test layout '$layout'"
9878         $LFS setstripe $layout $testfile || error "setstripe failed"
9879         $LFS getstripe -y $testfile
9880
9881         echo "get/set/list trusted.lov xattr ..." # b=10930
9882         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9883         [[ "$value" =~ "trusted.lov" ]] ||
9884                 error "can't get trusted.lov from $testfile"
9885         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9886                 error "getstripe failed"
9887
9888         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9889
9890         value=$(cut -d= -f2 <<<$value)
9891         # LU-13168: truncated xattr should fail if short lov_user_md header
9892         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9893                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9894         for len in $lens; do
9895                 echo "setfattr $len $testfile.2"
9896                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9897                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9898         done
9899         local stripe_size=$($LFS getstripe -S $testfile.2)
9900         local stripe_count=$($LFS getstripe -c $testfile.2)
9901         [[ $stripe_size -eq 65536 ]] ||
9902                 error "stripe size $stripe_size != 65536"
9903         [[ $stripe_count -eq $stripe_count_orig ]] ||
9904                 error "stripe count $stripe_count != $stripe_count_orig"
9905         rm $testfile $testfile.2
9906 }
9907
9908 test_102b() {
9909         [ -z "$(which setfattr 2>/dev/null)" ] &&
9910                 skip_env "could not find setfattr"
9911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9912
9913         # check plain layout
9914         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9915
9916         # and also check composite layout
9917         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9918
9919 }
9920 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9921
9922 test_102c() {
9923         [ -z "$(which setfattr 2>/dev/null)" ] &&
9924                 skip_env "could not find setfattr"
9925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9926
9927         # b10930: get/set/list lustre.lov xattr
9928         echo "get/set/list lustre.lov xattr ..."
9929         test_mkdir $DIR/$tdir
9930         chown $RUNAS_ID $DIR/$tdir
9931         local testfile=$DIR/$tdir/$tfile
9932         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9933                 error "setstripe failed"
9934         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9935                 error "getstripe failed"
9936         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9937         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9938
9939         local testfile2=${testfile}2
9940         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9941                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9942
9943         $RUNAS $MCREATE $testfile2
9944         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9945         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9946         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9947         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9948         [ $stripe_count -eq $STRIPECOUNT ] ||
9949                 error "stripe count $stripe_count != $STRIPECOUNT"
9950 }
9951 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9952
9953 compare_stripe_info1() {
9954         local stripe_index_all_zero=true
9955
9956         for num in 1 2 3 4; do
9957                 for count in $(seq 1 $STRIPE_COUNT); do
9958                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9959                                 local size=$((STRIPE_SIZE * num))
9960                                 local file=file"$num-$offset-$count"
9961                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9962                                 [[ $stripe_size -ne $size ]] &&
9963                                     error "$file: size $stripe_size != $size"
9964                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9965                                 # allow fewer stripes to be created, ORI-601
9966                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9967                                     error "$file: count $stripe_count != $count"
9968                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9969                                 [[ $stripe_index -ne 0 ]] &&
9970                                         stripe_index_all_zero=false
9971                         done
9972                 done
9973         done
9974         $stripe_index_all_zero &&
9975                 error "all files are being extracted starting from OST index 0"
9976         return 0
9977 }
9978
9979 have_xattrs_include() {
9980         tar --help | grep -q xattrs-include &&
9981                 echo --xattrs-include="lustre.*"
9982 }
9983
9984 test_102d() {
9985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9987
9988         XINC=$(have_xattrs_include)
9989         setup_test102
9990         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9991         cd $DIR/$tdir/$tdir
9992         compare_stripe_info1
9993 }
9994 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9995
9996 test_102f() {
9997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9998         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9999
10000         XINC=$(have_xattrs_include)
10001         setup_test102
10002         test_mkdir $DIR/$tdir.restore
10003         cd $DIR
10004         tar cf - --xattrs $tdir | tar xf - \
10005                 -C $DIR/$tdir.restore --xattrs $XINC
10006         cd $DIR/$tdir.restore/$tdir
10007         compare_stripe_info1
10008 }
10009 run_test 102f "tar copy files, not keep osts"
10010
10011 grow_xattr() {
10012         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10013                 skip "must have user_xattr"
10014         [ -z "$(which setfattr 2>/dev/null)" ] &&
10015                 skip_env "could not find setfattr"
10016         [ -z "$(which getfattr 2>/dev/null)" ] &&
10017                 skip_env "could not find getfattr"
10018
10019         local xsize=${1:-1024}  # in bytes
10020         local file=$DIR/$tfile
10021         local value="$(generate_string $xsize)"
10022         local xbig=trusted.big
10023         local toobig=$2
10024
10025         touch $file
10026         log "save $xbig on $file"
10027         if [ -z "$toobig" ]
10028         then
10029                 setfattr -n $xbig -v $value $file ||
10030                         error "saving $xbig on $file failed"
10031         else
10032                 setfattr -n $xbig -v $value $file &&
10033                         error "saving $xbig on $file succeeded"
10034                 return 0
10035         fi
10036
10037         local orig=$(get_xattr_value $xbig $file)
10038         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10039
10040         local xsml=trusted.sml
10041         log "save $xsml on $file"
10042         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10043
10044         local new=$(get_xattr_value $xbig $file)
10045         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10046
10047         log "grow $xsml on $file"
10048         setfattr -n $xsml -v "$value" $file ||
10049                 error "growing $xsml on $file failed"
10050
10051         new=$(get_xattr_value $xbig $file)
10052         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10053         log "$xbig still valid after growing $xsml"
10054
10055         rm -f $file
10056 }
10057
10058 test_102h() { # bug 15777
10059         grow_xattr 1024
10060 }
10061 run_test 102h "grow xattr from inside inode to external block"
10062
10063 test_102ha() {
10064         large_xattr_enabled || skip_env "ea_inode feature disabled"
10065
10066         echo "setting xattr of max xattr size: $(max_xattr_size)"
10067         grow_xattr $(max_xattr_size)
10068
10069         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10070         echo "This should fail:"
10071         grow_xattr $(($(max_xattr_size) + 10)) 1
10072 }
10073 run_test 102ha "grow xattr from inside inode to external inode"
10074
10075 test_102i() { # bug 17038
10076         [ -z "$(which getfattr 2>/dev/null)" ] &&
10077                 skip "could not find getfattr"
10078
10079         touch $DIR/$tfile
10080         ln -s $DIR/$tfile $DIR/${tfile}link
10081         getfattr -n trusted.lov $DIR/$tfile ||
10082                 error "lgetxattr on $DIR/$tfile failed"
10083         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10084                 grep -i "no such attr" ||
10085                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10086         rm -f $DIR/$tfile $DIR/${tfile}link
10087 }
10088 run_test 102i "lgetxattr test on symbolic link ============"
10089
10090 test_102j() {
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10093
10094         XINC=$(have_xattrs_include)
10095         setup_test102 "$RUNAS"
10096         chown $RUNAS_ID $DIR/$tdir
10097         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10098         cd $DIR/$tdir/$tdir
10099         compare_stripe_info1 "$RUNAS"
10100 }
10101 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10102
10103 test_102k() {
10104         [ -z "$(which setfattr 2>/dev/null)" ] &&
10105                 skip "could not find setfattr"
10106
10107         touch $DIR/$tfile
10108         # b22187 just check that does not crash for regular file.
10109         setfattr -n trusted.lov $DIR/$tfile
10110         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10111         local test_kdir=$DIR/$tdir
10112         test_mkdir $test_kdir
10113         local default_size=$($LFS getstripe -S $test_kdir)
10114         local default_count=$($LFS getstripe -c $test_kdir)
10115         local default_offset=$($LFS getstripe -i $test_kdir)
10116         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10117                 error 'dir setstripe failed'
10118         setfattr -n trusted.lov $test_kdir
10119         local stripe_size=$($LFS getstripe -S $test_kdir)
10120         local stripe_count=$($LFS getstripe -c $test_kdir)
10121         local stripe_offset=$($LFS getstripe -i $test_kdir)
10122         [ $stripe_size -eq $default_size ] ||
10123                 error "stripe size $stripe_size != $default_size"
10124         [ $stripe_count -eq $default_count ] ||
10125                 error "stripe count $stripe_count != $default_count"
10126         [ $stripe_offset -eq $default_offset ] ||
10127                 error "stripe offset $stripe_offset != $default_offset"
10128         rm -rf $DIR/$tfile $test_kdir
10129 }
10130 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10131
10132 test_102l() {
10133         [ -z "$(which getfattr 2>/dev/null)" ] &&
10134                 skip "could not find getfattr"
10135
10136         # LU-532 trusted. xattr is invisible to non-root
10137         local testfile=$DIR/$tfile
10138
10139         touch $testfile
10140
10141         echo "listxattr as user..."
10142         chown $RUNAS_ID $testfile
10143         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10144             grep -q "trusted" &&
10145                 error "$testfile trusted xattrs are user visible"
10146
10147         return 0;
10148 }
10149 run_test 102l "listxattr size test =================================="
10150
10151 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10152         local path=$DIR/$tfile
10153         touch $path
10154
10155         listxattr_size_check $path || error "listattr_size_check $path failed"
10156 }
10157 run_test 102m "Ensure listxattr fails on small bufffer ========"
10158
10159 cleanup_test102
10160
10161 getxattr() { # getxattr path name
10162         # Return the base64 encoding of the value of xattr name on path.
10163         local path=$1
10164         local name=$2
10165
10166         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10167         # file: $path
10168         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10169         #
10170         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10171
10172         getfattr --absolute-names --encoding=base64 --name=$name $path |
10173                 awk -F= -v name=$name '$1 == name {
10174                         print substr($0, index($0, "=") + 1);
10175         }'
10176 }
10177
10178 test_102n() { # LU-4101 mdt: protect internal xattrs
10179         [ -z "$(which setfattr 2>/dev/null)" ] &&
10180                 skip "could not find setfattr"
10181         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10182         then
10183                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10184         fi
10185
10186         local file0=$DIR/$tfile.0
10187         local file1=$DIR/$tfile.1
10188         local xattr0=$TMP/$tfile.0
10189         local xattr1=$TMP/$tfile.1
10190         local namelist="lov lma lmv link fid version som hsm"
10191         local name
10192         local value
10193
10194         rm -rf $file0 $file1 $xattr0 $xattr1
10195         touch $file0 $file1
10196
10197         # Get 'before' xattrs of $file1.
10198         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10199
10200         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10201                 namelist+=" lfsck_namespace"
10202         for name in $namelist; do
10203                 # Try to copy xattr from $file0 to $file1.
10204                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10205
10206                 setfattr --name=trusted.$name --value="$value" $file1 ||
10207                         error "setxattr 'trusted.$name' failed"
10208
10209                 # Try to set a garbage xattr.
10210                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10211
10212                 if [[ x$name == "xlov" ]]; then
10213                         setfattr --name=trusted.lov --value="$value" $file1 &&
10214                         error "setxattr invalid 'trusted.lov' success"
10215                 else
10216                         setfattr --name=trusted.$name --value="$value" $file1 ||
10217                                 error "setxattr invalid 'trusted.$name' failed"
10218                 fi
10219
10220                 # Try to remove the xattr from $file1. We don't care if this
10221                 # appears to succeed or fail, we just don't want there to be
10222                 # any changes or crashes.
10223                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10224         done
10225
10226         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10227         then
10228                 name="lfsck_ns"
10229                 # Try to copy xattr from $file0 to $file1.
10230                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10231
10232                 setfattr --name=trusted.$name --value="$value" $file1 ||
10233                         error "setxattr 'trusted.$name' failed"
10234
10235                 # Try to set a garbage xattr.
10236                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10237
10238                 setfattr --name=trusted.$name --value="$value" $file1 ||
10239                         error "setxattr 'trusted.$name' failed"
10240
10241                 # Try to remove the xattr from $file1. We don't care if this
10242                 # appears to succeed or fail, we just don't want there to be
10243                 # any changes or crashes.
10244                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10245         fi
10246
10247         # Get 'after' xattrs of file1.
10248         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10249
10250         if ! diff $xattr0 $xattr1; then
10251                 error "before and after xattrs of '$file1' differ"
10252         fi
10253
10254         rm -rf $file0 $file1 $xattr0 $xattr1
10255
10256         return 0
10257 }
10258 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10259
10260 test_102p() { # LU-4703 setxattr did not check ownership
10261         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10262                 skip "MDS needs to be at least 2.5.56"
10263
10264         local testfile=$DIR/$tfile
10265
10266         touch $testfile
10267
10268         echo "setfacl as user..."
10269         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10270         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10271
10272         echo "setfattr as user..."
10273         setfacl -m "u:$RUNAS_ID:---" $testfile
10274         $RUNAS setfattr -x system.posix_acl_access $testfile
10275         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10276 }
10277 run_test 102p "check setxattr(2) correctly fails without permission"
10278
10279 test_102q() {
10280         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10281                 skip "MDS needs to be at least 2.6.92"
10282
10283         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10284 }
10285 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10286
10287 test_102r() {
10288         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10289                 skip "MDS needs to be at least 2.6.93"
10290
10291         touch $DIR/$tfile || error "touch"
10292         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10293         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10294         rm $DIR/$tfile || error "rm"
10295
10296         #normal directory
10297         mkdir -p $DIR/$tdir || error "mkdir"
10298         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10299         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10300         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10301                 error "$testfile error deleting user.author1"
10302         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10303                 grep "user.$(basename $tdir)" &&
10304                 error "$tdir did not delete user.$(basename $tdir)"
10305         rmdir $DIR/$tdir || error "rmdir"
10306
10307         #striped directory
10308         test_mkdir $DIR/$tdir
10309         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10310         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10311         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10312                 error "$testfile error deleting user.author1"
10313         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10314                 grep "user.$(basename $tdir)" &&
10315                 error "$tdir did not delete user.$(basename $tdir)"
10316         rmdir $DIR/$tdir || error "rm striped dir"
10317 }
10318 run_test 102r "set EAs with empty values"
10319
10320 test_102s() {
10321         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10322                 skip "MDS needs to be at least 2.11.52"
10323
10324         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10325
10326         save_lustre_params client "llite.*.xattr_cache" > $save
10327
10328         for cache in 0 1; do
10329                 lctl set_param llite.*.xattr_cache=$cache
10330
10331                 rm -f $DIR/$tfile
10332                 touch $DIR/$tfile || error "touch"
10333                 for prefix in lustre security system trusted user; do
10334                         # Note getxattr() may fail with 'Operation not
10335                         # supported' or 'No such attribute' depending
10336                         # on prefix and cache.
10337                         getfattr -n $prefix.n102s $DIR/$tfile &&
10338                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10339                 done
10340         done
10341
10342         restore_lustre_params < $save
10343 }
10344 run_test 102s "getting nonexistent xattrs should fail"
10345
10346 test_102t() {
10347         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10348                 skip "MDS needs to be at least 2.11.52"
10349
10350         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10351
10352         save_lustre_params client "llite.*.xattr_cache" > $save
10353
10354         for cache in 0 1; do
10355                 lctl set_param llite.*.xattr_cache=$cache
10356
10357                 for buf_size in 0 256; do
10358                         rm -f $DIR/$tfile
10359                         touch $DIR/$tfile || error "touch"
10360                         setfattr -n user.multiop $DIR/$tfile
10361                         $MULTIOP $DIR/$tfile oa$buf_size ||
10362                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10363                 done
10364         done
10365
10366         restore_lustre_params < $save
10367 }
10368 run_test 102t "zero length xattr values handled correctly"
10369
10370 run_acl_subtest()
10371 {
10372     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10373     return $?
10374 }
10375
10376 test_103a() {
10377         [ "$UID" != 0 ] && skip "must run as root"
10378         $GSS && skip_env "could not run under gss"
10379         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10380                 skip_env "must have acl enabled"
10381         [ -z "$(which setfacl 2>/dev/null)" ] &&
10382                 skip_env "could not find setfacl"
10383         remote_mds_nodsh && skip "remote MDS with nodsh"
10384
10385         gpasswd -a daemon bin                           # LU-5641
10386         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10387
10388         declare -a identity_old
10389
10390         for num in $(seq $MDSCOUNT); do
10391                 switch_identity $num true || identity_old[$num]=$?
10392         done
10393
10394         SAVE_UMASK=$(umask)
10395         umask 0022
10396         mkdir -p $DIR/$tdir
10397         cd $DIR/$tdir
10398
10399         echo "performing cp ..."
10400         run_acl_subtest cp || error "run_acl_subtest cp failed"
10401         echo "performing getfacl-noacl..."
10402         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10403         echo "performing misc..."
10404         run_acl_subtest misc || error  "misc test failed"
10405         echo "performing permissions..."
10406         run_acl_subtest permissions || error "permissions failed"
10407         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10408         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10409                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10410                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10411         then
10412                 echo "performing permissions xattr..."
10413                 run_acl_subtest permissions_xattr ||
10414                         error "permissions_xattr failed"
10415         fi
10416         echo "performing setfacl..."
10417         run_acl_subtest setfacl || error  "setfacl test failed"
10418
10419         # inheritance test got from HP
10420         echo "performing inheritance..."
10421         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10422         chmod +x make-tree || error "chmod +x failed"
10423         run_acl_subtest inheritance || error "inheritance test failed"
10424         rm -f make-tree
10425
10426         echo "LU-974 ignore umask when acl is enabled..."
10427         run_acl_subtest 974 || error "LU-974 umask test failed"
10428         if [ $MDSCOUNT -ge 2 ]; then
10429                 run_acl_subtest 974_remote ||
10430                         error "LU-974 umask test failed under remote dir"
10431         fi
10432
10433         echo "LU-2561 newly created file is same size as directory..."
10434         if [ "$mds1_FSTYPE" != "zfs" ]; then
10435                 run_acl_subtest 2561 || error "LU-2561 test failed"
10436         else
10437                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10438         fi
10439
10440         run_acl_subtest 4924 || error "LU-4924 test failed"
10441
10442         cd $SAVE_PWD
10443         umask $SAVE_UMASK
10444
10445         for num in $(seq $MDSCOUNT); do
10446                 if [ "${identity_old[$num]}" = 1 ]; then
10447                         switch_identity $num false || identity_old[$num]=$?
10448                 fi
10449         done
10450 }
10451 run_test 103a "acl test"
10452
10453 test_103b() {
10454         declare -a pids
10455         local U
10456
10457         for U in {0..511}; do
10458                 {
10459                 local O=$(printf "%04o" $U)
10460
10461                 umask $(printf "%04o" $((511 ^ $O)))
10462                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10463                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10464
10465                 (( $S == ($O & 0666) )) ||
10466                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10467
10468                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10469                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10470                 (( $S == ($O & 0666) )) ||
10471                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10472
10473                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10474                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10475                 (( $S == ($O & 0666) )) ||
10476                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10477                 rm -f $DIR/$tfile.[smp]$0
10478                 } &
10479                 local pid=$!
10480
10481                 # limit the concurrently running threads to 64. LU-11878
10482                 local idx=$((U % 64))
10483                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10484                 pids[idx]=$pid
10485         done
10486         wait
10487 }
10488 run_test 103b "umask lfs setstripe"
10489
10490 test_103c() {
10491         mkdir -p $DIR/$tdir
10492         cp -rp $DIR/$tdir $DIR/$tdir.bak
10493
10494         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10495                 error "$DIR/$tdir shouldn't contain default ACL"
10496         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10497                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10498         true
10499 }
10500 run_test 103c "'cp -rp' won't set empty acl"
10501
10502 test_104a() {
10503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10504
10505         touch $DIR/$tfile
10506         lfs df || error "lfs df failed"
10507         lfs df -ih || error "lfs df -ih failed"
10508         lfs df -h $DIR || error "lfs df -h $DIR failed"
10509         lfs df -i $DIR || error "lfs df -i $DIR failed"
10510         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10511         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10512
10513         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10514         lctl --device %$OSC deactivate
10515         lfs df || error "lfs df with deactivated OSC failed"
10516         lctl --device %$OSC activate
10517         # wait the osc back to normal
10518         wait_osc_import_ready client ost
10519
10520         lfs df || error "lfs df with reactivated OSC failed"
10521         rm -f $DIR/$tfile
10522 }
10523 run_test 104a "lfs df [-ih] [path] test ========================="
10524
10525 test_104b() {
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527         [ $RUNAS_ID -eq $UID ] &&
10528                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10529
10530         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10531                         grep "Permission denied" | wc -l)))
10532         if [ $denied_cnt -ne 0 ]; then
10533                 error "lfs check servers test failed"
10534         fi
10535 }
10536 run_test 104b "$RUNAS lfs check servers test ===================="
10537
10538 test_105a() {
10539         # doesn't work on 2.4 kernels
10540         touch $DIR/$tfile
10541         if $(flock_is_enabled); then
10542                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10543         else
10544                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10545         fi
10546         rm -f $DIR/$tfile
10547 }
10548 run_test 105a "flock when mounted without -o flock test ========"
10549
10550 test_105b() {
10551         touch $DIR/$tfile
10552         if $(flock_is_enabled); then
10553                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10554         else
10555                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10556         fi
10557         rm -f $DIR/$tfile
10558 }
10559 run_test 105b "fcntl when mounted without -o flock test ========"
10560
10561 test_105c() {
10562         touch $DIR/$tfile
10563         if $(flock_is_enabled); then
10564                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10565         else
10566                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10567         fi
10568         rm -f $DIR/$tfile
10569 }
10570 run_test 105c "lockf when mounted without -o flock test"
10571
10572 test_105d() { # bug 15924
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10574
10575         test_mkdir $DIR/$tdir
10576         flock_is_enabled || skip_env "mount w/o flock enabled"
10577         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10578         $LCTL set_param fail_loc=0x80000315
10579         flocks_test 2 $DIR/$tdir
10580 }
10581 run_test 105d "flock race (should not freeze) ========"
10582
10583 test_105e() { # bug 22660 && 22040
10584         flock_is_enabled || skip_env "mount w/o flock enabled"
10585
10586         touch $DIR/$tfile
10587         flocks_test 3 $DIR/$tfile
10588 }
10589 run_test 105e "Two conflicting flocks from same process"
10590
10591 test_106() { #bug 10921
10592         test_mkdir $DIR/$tdir
10593         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10594         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10595 }
10596 run_test 106 "attempt exec of dir followed by chown of that dir"
10597
10598 test_107() {
10599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10600
10601         CDIR=`pwd`
10602         local file=core
10603
10604         cd $DIR
10605         rm -f $file
10606
10607         local save_pattern=$(sysctl -n kernel.core_pattern)
10608         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10609         sysctl -w kernel.core_pattern=$file
10610         sysctl -w kernel.core_uses_pid=0
10611
10612         ulimit -c unlimited
10613         sleep 60 &
10614         SLEEPPID=$!
10615
10616         sleep 1
10617
10618         kill -s 11 $SLEEPPID
10619         wait $SLEEPPID
10620         if [ -e $file ]; then
10621                 size=`stat -c%s $file`
10622                 [ $size -eq 0 ] && error "Fail to create core file $file"
10623         else
10624                 error "Fail to create core file $file"
10625         fi
10626         rm -f $file
10627         sysctl -w kernel.core_pattern=$save_pattern
10628         sysctl -w kernel.core_uses_pid=$save_uses_pid
10629         cd $CDIR
10630 }
10631 run_test 107 "Coredump on SIG"
10632
10633 test_110() {
10634         test_mkdir $DIR/$tdir
10635         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10636         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10637                 error "mkdir with 256 char should fail, but did not"
10638         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10639                 error "create with 255 char failed"
10640         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10641                 error "create with 256 char should fail, but did not"
10642
10643         ls -l $DIR/$tdir
10644         rm -rf $DIR/$tdir
10645 }
10646 run_test 110 "filename length checking"
10647
10648 #
10649 # Purpose: To verify dynamic thread (OSS) creation.
10650 #
10651 test_115() {
10652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10653         remote_ost_nodsh && skip "remote OST with nodsh"
10654
10655         # Lustre does not stop service threads once they are started.
10656         # Reset number of running threads to default.
10657         stopall
10658         setupall
10659
10660         local OSTIO_pre
10661         local save_params="$TMP/sanity-$TESTNAME.parameters"
10662
10663         # Get ll_ost_io count before I/O
10664         OSTIO_pre=$(do_facet ost1 \
10665                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10666         # Exit if lustre is not running (ll_ost_io not running).
10667         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10668
10669         echo "Starting with $OSTIO_pre threads"
10670         local thread_max=$((OSTIO_pre * 2))
10671         local rpc_in_flight=$((thread_max * 2))
10672         # Number of I/O Process proposed to be started.
10673         local nfiles
10674         local facets=$(get_facets OST)
10675
10676         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10677         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10678
10679         # Set in_flight to $rpc_in_flight
10680         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10681                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10682         nfiles=${rpc_in_flight}
10683         # Set ost thread_max to $thread_max
10684         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10685
10686         # 5 Minutes should be sufficient for max number of OSS
10687         # threads(thread_max) to be created.
10688         local timeout=300
10689
10690         # Start I/O.
10691         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10692         test_mkdir $DIR/$tdir
10693         for i in $(seq $nfiles); do
10694                 local file=$DIR/$tdir/${tfile}-$i
10695                 $LFS setstripe -c -1 -i 0 $file
10696                 ($WTL $file $timeout)&
10697         done
10698
10699         # I/O Started - Wait for thread_started to reach thread_max or report
10700         # error if thread_started is more than thread_max.
10701         echo "Waiting for thread_started to reach thread_max"
10702         local thread_started=0
10703         local end_time=$((SECONDS + timeout))
10704
10705         while [ $SECONDS -le $end_time ] ; do
10706                 echo -n "."
10707                 # Get ost i/o thread_started count.
10708                 thread_started=$(do_facet ost1 \
10709                         "$LCTL get_param \
10710                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10711                 # Break out if thread_started is equal/greater than thread_max
10712                 if [[ $thread_started -ge $thread_max ]]; then
10713                         echo ll_ost_io thread_started $thread_started, \
10714                                 equal/greater than thread_max $thread_max
10715                         break
10716                 fi
10717                 sleep 1
10718         done
10719
10720         # Cleanup - We have the numbers, Kill i/o jobs if running.
10721         jobcount=($(jobs -p))
10722         for i in $(seq 0 $((${#jobcount[@]}-1)))
10723         do
10724                 kill -9 ${jobcount[$i]}
10725                 if [ $? -ne 0 ] ; then
10726                         echo Warning: \
10727                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10728                 fi
10729         done
10730
10731         # Cleanup files left by WTL binary.
10732         for i in $(seq $nfiles); do
10733                 local file=$DIR/$tdir/${tfile}-$i
10734                 rm -rf $file
10735                 if [ $? -ne 0 ] ; then
10736                         echo "Warning: Failed to delete file $file"
10737                 fi
10738         done
10739
10740         restore_lustre_params <$save_params
10741         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10742
10743         # Error out if no new thread has started or Thread started is greater
10744         # than thread max.
10745         if [[ $thread_started -le $OSTIO_pre ||
10746                         $thread_started -gt $thread_max ]]; then
10747                 error "ll_ost_io: thread_started $thread_started" \
10748                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10749                       "No new thread started or thread started greater " \
10750                       "than thread_max."
10751         fi
10752 }
10753 run_test 115 "verify dynamic thread creation===================="
10754
10755 free_min_max () {
10756         wait_delete_completed
10757         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10758         echo "OST kbytes available: ${AVAIL[@]}"
10759         MAXV=${AVAIL[0]}
10760         MAXI=0
10761         MINV=${AVAIL[0]}
10762         MINI=0
10763         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10764                 #echo OST $i: ${AVAIL[i]}kb
10765                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10766                         MAXV=${AVAIL[i]}
10767                         MAXI=$i
10768                 fi
10769                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10770                         MINV=${AVAIL[i]}
10771                         MINI=$i
10772                 fi
10773         done
10774         echo "Min free space: OST $MINI: $MINV"
10775         echo "Max free space: OST $MAXI: $MAXV"
10776 }
10777
10778 test_116a() { # was previously test_116()
10779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10781         remote_mds_nodsh && skip "remote MDS with nodsh"
10782
10783         echo -n "Free space priority "
10784         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10785                 head -n1
10786         declare -a AVAIL
10787         free_min_max
10788
10789         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10790         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10791         trap simple_cleanup_common EXIT
10792
10793         # Check if we need to generate uneven OSTs
10794         test_mkdir -p $DIR/$tdir/OST${MINI}
10795         local FILL=$((MINV / 4))
10796         local DIFF=$((MAXV - MINV))
10797         local DIFF2=$((DIFF * 100 / MINV))
10798
10799         local threshold=$(do_facet $SINGLEMDS \
10800                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10801         threshold=${threshold%%%}
10802         echo -n "Check for uneven OSTs: "
10803         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10804
10805         if [[ $DIFF2 -gt $threshold ]]; then
10806                 echo "ok"
10807                 echo "Don't need to fill OST$MINI"
10808         else
10809                 # generate uneven OSTs. Write 2% over the QOS threshold value
10810                 echo "no"
10811                 DIFF=$((threshold - DIFF2 + 2))
10812                 DIFF2=$((MINV * DIFF / 100))
10813                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10814                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10815                         error "setstripe failed"
10816                 DIFF=$((DIFF2 / 2048))
10817                 i=0
10818                 while [ $i -lt $DIFF ]; do
10819                         i=$((i + 1))
10820                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10821                                 bs=2M count=1 2>/dev/null
10822                         echo -n .
10823                 done
10824                 echo .
10825                 sync
10826                 sleep_maxage
10827                 free_min_max
10828         fi
10829
10830         DIFF=$((MAXV - MINV))
10831         DIFF2=$((DIFF * 100 / MINV))
10832         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10833         if [ $DIFF2 -gt $threshold ]; then
10834                 echo "ok"
10835         else
10836                 echo "failed - QOS mode won't be used"
10837                 simple_cleanup_common
10838                 skip "QOS imbalance criteria not met"
10839         fi
10840
10841         MINI1=$MINI
10842         MINV1=$MINV
10843         MAXI1=$MAXI
10844         MAXV1=$MAXV
10845
10846         # now fill using QOS
10847         $LFS setstripe -c 1 $DIR/$tdir
10848         FILL=$((FILL / 200))
10849         if [ $FILL -gt 600 ]; then
10850                 FILL=600
10851         fi
10852         echo "writing $FILL files to QOS-assigned OSTs"
10853         i=0
10854         while [ $i -lt $FILL ]; do
10855                 i=$((i + 1))
10856                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10857                         count=1 2>/dev/null
10858                 echo -n .
10859         done
10860         echo "wrote $i 200k files"
10861         sync
10862         sleep_maxage
10863
10864         echo "Note: free space may not be updated, so measurements might be off"
10865         free_min_max
10866         DIFF2=$((MAXV - MINV))
10867         echo "free space delta: orig $DIFF final $DIFF2"
10868         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10869         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10870         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10871         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10872         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10873         if [[ $DIFF -gt 0 ]]; then
10874                 FILL=$((DIFF2 * 100 / DIFF - 100))
10875                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10876         fi
10877
10878         # Figure out which files were written where
10879         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10880                awk '/'$MINI1': / {print $2; exit}')
10881         echo $UUID
10882         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10883         echo "$MINC files created on smaller OST $MINI1"
10884         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10885                awk '/'$MAXI1': / {print $2; exit}')
10886         echo $UUID
10887         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10888         echo "$MAXC files created on larger OST $MAXI1"
10889         if [[ $MINC -gt 0 ]]; then
10890                 FILL=$((MAXC * 100 / MINC - 100))
10891                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10892         fi
10893         [[ $MAXC -gt $MINC ]] ||
10894                 error_ignore LU-9 "stripe QOS didn't balance free space"
10895         simple_cleanup_common
10896 }
10897 run_test 116a "stripe QOS: free space balance ==================="
10898
10899 test_116b() { # LU-2093
10900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10901         remote_mds_nodsh && skip "remote MDS with nodsh"
10902
10903 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10904         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10905                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10906         [ -z "$old_rr" ] && skip "no QOS"
10907         do_facet $SINGLEMDS lctl set_param \
10908                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10909         mkdir -p $DIR/$tdir
10910         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10911         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10912         do_facet $SINGLEMDS lctl set_param fail_loc=0
10913         rm -rf $DIR/$tdir
10914         do_facet $SINGLEMDS lctl set_param \
10915                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10916 }
10917 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10918
10919 test_117() # bug 10891
10920 {
10921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10922
10923         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10924         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10925         lctl set_param fail_loc=0x21e
10926         > $DIR/$tfile || error "truncate failed"
10927         lctl set_param fail_loc=0
10928         echo "Truncate succeeded."
10929         rm -f $DIR/$tfile
10930 }
10931 run_test 117 "verify osd extend =========="
10932
10933 NO_SLOW_RESENDCOUNT=4
10934 export OLD_RESENDCOUNT=""
10935 set_resend_count () {
10936         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10937         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10938         lctl set_param -n $PROC_RESENDCOUNT $1
10939         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10940 }
10941
10942 # for reduce test_118* time (b=14842)
10943 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10944
10945 # Reset async IO behavior after error case
10946 reset_async() {
10947         FILE=$DIR/reset_async
10948
10949         # Ensure all OSCs are cleared
10950         $LFS setstripe -c -1 $FILE
10951         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10952         sync
10953         rm $FILE
10954 }
10955
10956 test_118a() #bug 11710
10957 {
10958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10959
10960         reset_async
10961
10962         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10963         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10965
10966         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10967                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10968                 return 1;
10969         fi
10970         rm -f $DIR/$tfile
10971 }
10972 run_test 118a "verify O_SYNC works =========="
10973
10974 test_118b()
10975 {
10976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10977         remote_ost_nodsh && skip "remote OST with nodsh"
10978
10979         reset_async
10980
10981         #define OBD_FAIL_SRV_ENOENT 0x217
10982         set_nodes_failloc "$(osts_nodes)" 0x217
10983         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10984         RC=$?
10985         set_nodes_failloc "$(osts_nodes)" 0
10986         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10987         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10988                     grep -c writeback)
10989
10990         if [[ $RC -eq 0 ]]; then
10991                 error "Must return error due to dropped pages, rc=$RC"
10992                 return 1;
10993         fi
10994
10995         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10996                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10997                 return 1;
10998         fi
10999
11000         echo "Dirty pages not leaked on ENOENT"
11001
11002         # Due to the above error the OSC will issue all RPCs syncronously
11003         # until a subsequent RPC completes successfully without error.
11004         $MULTIOP $DIR/$tfile Ow4096yc
11005         rm -f $DIR/$tfile
11006
11007         return 0
11008 }
11009 run_test 118b "Reclaim dirty pages on fatal error =========="
11010
11011 test_118c()
11012 {
11013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11014
11015         # for 118c, restore the original resend count, LU-1940
11016         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11017                                 set_resend_count $OLD_RESENDCOUNT
11018         remote_ost_nodsh && skip "remote OST with nodsh"
11019
11020         reset_async
11021
11022         #define OBD_FAIL_OST_EROFS               0x216
11023         set_nodes_failloc "$(osts_nodes)" 0x216
11024
11025         # multiop should block due to fsync until pages are written
11026         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11027         MULTIPID=$!
11028         sleep 1
11029
11030         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11031                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11032         fi
11033
11034         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11035                     grep -c writeback)
11036         if [[ $WRITEBACK -eq 0 ]]; then
11037                 error "No page in writeback, writeback=$WRITEBACK"
11038         fi
11039
11040         set_nodes_failloc "$(osts_nodes)" 0
11041         wait $MULTIPID
11042         RC=$?
11043         if [[ $RC -ne 0 ]]; then
11044                 error "Multiop fsync failed, rc=$RC"
11045         fi
11046
11047         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11048         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11049                     grep -c writeback)
11050         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11051                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11052         fi
11053
11054         rm -f $DIR/$tfile
11055         echo "Dirty pages flushed via fsync on EROFS"
11056         return 0
11057 }
11058 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11059
11060 # continue to use small resend count to reduce test_118* time (b=14842)
11061 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11062
11063 test_118d()
11064 {
11065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11066         remote_ost_nodsh && skip "remote OST with nodsh"
11067
11068         reset_async
11069
11070         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11071         set_nodes_failloc "$(osts_nodes)" 0x214
11072         # multiop should block due to fsync until pages are written
11073         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11074         MULTIPID=$!
11075         sleep 1
11076
11077         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11078                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11079         fi
11080
11081         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11082                     grep -c writeback)
11083         if [[ $WRITEBACK -eq 0 ]]; then
11084                 error "No page in writeback, writeback=$WRITEBACK"
11085         fi
11086
11087         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11088         set_nodes_failloc "$(osts_nodes)" 0
11089
11090         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11091         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11092                     grep -c writeback)
11093         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11094                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11095         fi
11096
11097         rm -f $DIR/$tfile
11098         echo "Dirty pages gaurenteed flushed via fsync"
11099         return 0
11100 }
11101 run_test 118d "Fsync validation inject a delay of the bulk =========="
11102
11103 test_118f() {
11104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11105
11106         reset_async
11107
11108         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11109         lctl set_param fail_loc=0x8000040a
11110
11111         # Should simulate EINVAL error which is fatal
11112         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11113         RC=$?
11114         if [[ $RC -eq 0 ]]; then
11115                 error "Must return error due to dropped pages, rc=$RC"
11116         fi
11117
11118         lctl set_param fail_loc=0x0
11119
11120         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11121         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11122         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11123                     grep -c writeback)
11124         if [[ $LOCKED -ne 0 ]]; then
11125                 error "Locked pages remain in cache, locked=$LOCKED"
11126         fi
11127
11128         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11129                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11130         fi
11131
11132         rm -f $DIR/$tfile
11133         echo "No pages locked after fsync"
11134
11135         reset_async
11136         return 0
11137 }
11138 run_test 118f "Simulate unrecoverable OSC side error =========="
11139
11140 test_118g() {
11141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11142
11143         reset_async
11144
11145         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11146         lctl set_param fail_loc=0x406
11147
11148         # simulate local -ENOMEM
11149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11150         RC=$?
11151
11152         lctl set_param fail_loc=0
11153         if [[ $RC -eq 0 ]]; then
11154                 error "Must return error due to dropped pages, rc=$RC"
11155         fi
11156
11157         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11158         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11159         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11160                         grep -c writeback)
11161         if [[ $LOCKED -ne 0 ]]; then
11162                 error "Locked pages remain in cache, locked=$LOCKED"
11163         fi
11164
11165         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11166                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11167         fi
11168
11169         rm -f $DIR/$tfile
11170         echo "No pages locked after fsync"
11171
11172         reset_async
11173         return 0
11174 }
11175 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11176
11177 test_118h() {
11178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11179         remote_ost_nodsh && skip "remote OST with nodsh"
11180
11181         reset_async
11182
11183         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11184         set_nodes_failloc "$(osts_nodes)" 0x20e
11185         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11186         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11187         RC=$?
11188
11189         set_nodes_failloc "$(osts_nodes)" 0
11190         if [[ $RC -eq 0 ]]; then
11191                 error "Must return error due to dropped pages, rc=$RC"
11192         fi
11193
11194         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11195         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11196         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11197                     grep -c writeback)
11198         if [[ $LOCKED -ne 0 ]]; then
11199                 error "Locked pages remain in cache, locked=$LOCKED"
11200         fi
11201
11202         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11203                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11204         fi
11205
11206         rm -f $DIR/$tfile
11207         echo "No pages locked after fsync"
11208
11209         return 0
11210 }
11211 run_test 118h "Verify timeout in handling recoverables errors  =========="
11212
11213 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11214
11215 test_118i() {
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         remote_ost_nodsh && skip "remote OST with nodsh"
11218
11219         reset_async
11220
11221         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11222         set_nodes_failloc "$(osts_nodes)" 0x20e
11223
11224         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11226         PID=$!
11227         sleep 5
11228         set_nodes_failloc "$(osts_nodes)" 0
11229
11230         wait $PID
11231         RC=$?
11232         if [[ $RC -ne 0 ]]; then
11233                 error "got error, but should be not, rc=$RC"
11234         fi
11235
11236         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11237         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11238         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11239         if [[ $LOCKED -ne 0 ]]; then
11240                 error "Locked pages remain in cache, locked=$LOCKED"
11241         fi
11242
11243         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11244                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11245         fi
11246
11247         rm -f $DIR/$tfile
11248         echo "No pages locked after fsync"
11249
11250         return 0
11251 }
11252 run_test 118i "Fix error before timeout in recoverable error  =========="
11253
11254 [ "$SLOW" = "no" ] && set_resend_count 4
11255
11256 test_118j() {
11257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11258         remote_ost_nodsh && skip "remote OST with nodsh"
11259
11260         reset_async
11261
11262         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11263         set_nodes_failloc "$(osts_nodes)" 0x220
11264
11265         # return -EIO from OST
11266         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11267         RC=$?
11268         set_nodes_failloc "$(osts_nodes)" 0x0
11269         if [[ $RC -eq 0 ]]; then
11270                 error "Must return error due to dropped pages, rc=$RC"
11271         fi
11272
11273         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11274         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11275         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11276         if [[ $LOCKED -ne 0 ]]; then
11277                 error "Locked pages remain in cache, locked=$LOCKED"
11278         fi
11279
11280         # in recoverable error on OST we want resend and stay until it finished
11281         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11282                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11283         fi
11284
11285         rm -f $DIR/$tfile
11286         echo "No pages locked after fsync"
11287
11288         return 0
11289 }
11290 run_test 118j "Simulate unrecoverable OST side error =========="
11291
11292 test_118k()
11293 {
11294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11295         remote_ost_nodsh && skip "remote OSTs with nodsh"
11296
11297         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11298         set_nodes_failloc "$(osts_nodes)" 0x20e
11299         test_mkdir $DIR/$tdir
11300
11301         for ((i=0;i<10;i++)); do
11302                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11303                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11304                 SLEEPPID=$!
11305                 sleep 0.500s
11306                 kill $SLEEPPID
11307                 wait $SLEEPPID
11308         done
11309
11310         set_nodes_failloc "$(osts_nodes)" 0
11311         rm -rf $DIR/$tdir
11312 }
11313 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11314
11315 test_118l() # LU-646
11316 {
11317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11318
11319         test_mkdir $DIR/$tdir
11320         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11321         rm -rf $DIR/$tdir
11322 }
11323 run_test 118l "fsync dir"
11324
11325 test_118m() # LU-3066
11326 {
11327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11328
11329         test_mkdir $DIR/$tdir
11330         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11331         rm -rf $DIR/$tdir
11332 }
11333 run_test 118m "fdatasync dir ========="
11334
11335 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11336
11337 test_118n()
11338 {
11339         local begin
11340         local end
11341
11342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11343         remote_ost_nodsh && skip "remote OSTs with nodsh"
11344
11345         # Sleep to avoid a cached response.
11346         #define OBD_STATFS_CACHE_SECONDS 1
11347         sleep 2
11348
11349         # Inject a 10 second delay in the OST_STATFS handler.
11350         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11351         set_nodes_failloc "$(osts_nodes)" 0x242
11352
11353         begin=$SECONDS
11354         stat --file-system $MOUNT > /dev/null
11355         end=$SECONDS
11356
11357         set_nodes_failloc "$(osts_nodes)" 0
11358
11359         if ((end - begin > 20)); then
11360             error "statfs took $((end - begin)) seconds, expected 10"
11361         fi
11362 }
11363 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11364
11365 test_119a() # bug 11737
11366 {
11367         BSIZE=$((512 * 1024))
11368         directio write $DIR/$tfile 0 1 $BSIZE
11369         # We ask to read two blocks, which is more than a file size.
11370         # directio will indicate an error when requested and actual
11371         # sizes aren't equeal (a normal situation in this case) and
11372         # print actual read amount.
11373         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11374         if [ "$NOB" != "$BSIZE" ]; then
11375                 error "read $NOB bytes instead of $BSIZE"
11376         fi
11377         rm -f $DIR/$tfile
11378 }
11379 run_test 119a "Short directIO read must return actual read amount"
11380
11381 test_119b() # bug 11737
11382 {
11383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11384
11385         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11387         sync
11388         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11389                 error "direct read failed"
11390         rm -f $DIR/$tfile
11391 }
11392 run_test 119b "Sparse directIO read must return actual read amount"
11393
11394 test_119c() # bug 13099
11395 {
11396         BSIZE=1048576
11397         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11398         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11399         rm -f $DIR/$tfile
11400 }
11401 run_test 119c "Testing for direct read hitting hole"
11402
11403 test_119d() # bug 15950
11404 {
11405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11406
11407         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11408         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11409         BSIZE=1048576
11410         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11411         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11412         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11413         lctl set_param fail_loc=0x40d
11414         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11415         pid_dio=$!
11416         sleep 1
11417         cat $DIR/$tfile > /dev/null &
11418         lctl set_param fail_loc=0
11419         pid_reads=$!
11420         wait $pid_dio
11421         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11422         sleep 2
11423         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11424         error "the read rpcs have not completed in 2s"
11425         rm -f $DIR/$tfile
11426         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11427 }
11428 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11429
11430 test_120a() {
11431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11432         remote_mds_nodsh && skip "remote MDS with nodsh"
11433         test_mkdir -i0 -c1 $DIR/$tdir
11434         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11435                 skip_env "no early lock cancel on server"
11436
11437         lru_resize_disable mdc
11438         lru_resize_disable osc
11439         cancel_lru_locks mdc
11440         # asynchronous object destroy at MDT could cause bl ast to client
11441         cancel_lru_locks osc
11442
11443         stat $DIR/$tdir > /dev/null
11444         can1=$(do_facet mds1 \
11445                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11446                awk '/ldlm_cancel/ {print $2}')
11447         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11448                awk '/ldlm_bl_callback/ {print $2}')
11449         test_mkdir -i0 -c1 $DIR/$tdir/d1
11450         can2=$(do_facet mds1 \
11451                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11452                awk '/ldlm_cancel/ {print $2}')
11453         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11454                awk '/ldlm_bl_callback/ {print $2}')
11455         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11456         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11457         lru_resize_enable mdc
11458         lru_resize_enable osc
11459 }
11460 run_test 120a "Early Lock Cancel: mkdir test"
11461
11462 test_120b() {
11463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11464         remote_mds_nodsh && skip "remote MDS with nodsh"
11465         test_mkdir $DIR/$tdir
11466         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11467                 skip_env "no early lock cancel on server"
11468
11469         lru_resize_disable mdc
11470         lru_resize_disable osc
11471         cancel_lru_locks mdc
11472         stat $DIR/$tdir > /dev/null
11473         can1=$(do_facet $SINGLEMDS \
11474                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11475                awk '/ldlm_cancel/ {print $2}')
11476         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11477                awk '/ldlm_bl_callback/ {print $2}')
11478         touch $DIR/$tdir/f1
11479         can2=$(do_facet $SINGLEMDS \
11480                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11481                awk '/ldlm_cancel/ {print $2}')
11482         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11483                awk '/ldlm_bl_callback/ {print $2}')
11484         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11485         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11486         lru_resize_enable mdc
11487         lru_resize_enable osc
11488 }
11489 run_test 120b "Early Lock Cancel: create test"
11490
11491 test_120c() {
11492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11493         remote_mds_nodsh && skip "remote MDS with nodsh"
11494         test_mkdir -i0 -c1 $DIR/$tdir
11495         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11496                 skip "no early lock cancel on server"
11497
11498         lru_resize_disable mdc
11499         lru_resize_disable osc
11500         test_mkdir -i0 -c1 $DIR/$tdir/d1
11501         test_mkdir -i0 -c1 $DIR/$tdir/d2
11502         touch $DIR/$tdir/d1/f1
11503         cancel_lru_locks mdc
11504         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11505         can1=$(do_facet mds1 \
11506                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11507                awk '/ldlm_cancel/ {print $2}')
11508         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11509                awk '/ldlm_bl_callback/ {print $2}')
11510         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11511         can2=$(do_facet mds1 \
11512                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11513                awk '/ldlm_cancel/ {print $2}')
11514         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11515                awk '/ldlm_bl_callback/ {print $2}')
11516         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11517         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11518         lru_resize_enable mdc
11519         lru_resize_enable osc
11520 }
11521 run_test 120c "Early Lock Cancel: link test"
11522
11523 test_120d() {
11524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11525         remote_mds_nodsh && skip "remote MDS with nodsh"
11526         test_mkdir -i0 -c1 $DIR/$tdir
11527         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11528                 skip_env "no early lock cancel on server"
11529
11530         lru_resize_disable mdc
11531         lru_resize_disable osc
11532         touch $DIR/$tdir
11533         cancel_lru_locks mdc
11534         stat $DIR/$tdir > /dev/null
11535         can1=$(do_facet mds1 \
11536                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11537                awk '/ldlm_cancel/ {print $2}')
11538         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11539                awk '/ldlm_bl_callback/ {print $2}')
11540         chmod a+x $DIR/$tdir
11541         can2=$(do_facet mds1 \
11542                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11543                awk '/ldlm_cancel/ {print $2}')
11544         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11545                awk '/ldlm_bl_callback/ {print $2}')
11546         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11547         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11548         lru_resize_enable mdc
11549         lru_resize_enable osc
11550 }
11551 run_test 120d "Early Lock Cancel: setattr test"
11552
11553 test_120e() {
11554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11555         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11556                 skip_env "no early lock cancel on server"
11557         remote_mds_nodsh && skip "remote MDS with nodsh"
11558
11559         local dlmtrace_set=false
11560
11561         test_mkdir -i0 -c1 $DIR/$tdir
11562         lru_resize_disable mdc
11563         lru_resize_disable osc
11564         ! $LCTL get_param debug | grep -q dlmtrace &&
11565                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11566         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11567         cancel_lru_locks mdc
11568         cancel_lru_locks osc
11569         dd if=$DIR/$tdir/f1 of=/dev/null
11570         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11571         # XXX client can not do early lock cancel of OST lock
11572         # during unlink (LU-4206), so cancel osc lock now.
11573         sleep 2
11574         cancel_lru_locks osc
11575         can1=$(do_facet mds1 \
11576                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11577                awk '/ldlm_cancel/ {print $2}')
11578         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11579                awk '/ldlm_bl_callback/ {print $2}')
11580         unlink $DIR/$tdir/f1
11581         sleep 5
11582         can2=$(do_facet mds1 \
11583                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11584                awk '/ldlm_cancel/ {print $2}')
11585         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11586                awk '/ldlm_bl_callback/ {print $2}')
11587         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11588                 $LCTL dk $TMP/cancel.debug.txt
11589         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11590                 $LCTL dk $TMP/blocking.debug.txt
11591         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11592         lru_resize_enable mdc
11593         lru_resize_enable osc
11594 }
11595 run_test 120e "Early Lock Cancel: unlink test"
11596
11597 test_120f() {
11598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11599         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11600                 skip_env "no early lock cancel on server"
11601         remote_mds_nodsh && skip "remote MDS with nodsh"
11602
11603         test_mkdir -i0 -c1 $DIR/$tdir
11604         lru_resize_disable mdc
11605         lru_resize_disable osc
11606         test_mkdir -i0 -c1 $DIR/$tdir/d1
11607         test_mkdir -i0 -c1 $DIR/$tdir/d2
11608         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11609         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11610         cancel_lru_locks mdc
11611         cancel_lru_locks osc
11612         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11613         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11614         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11615         # XXX client can not do early lock cancel of OST lock
11616         # during rename (LU-4206), so cancel osc lock now.
11617         sleep 2
11618         cancel_lru_locks osc
11619         can1=$(do_facet mds1 \
11620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11621                awk '/ldlm_cancel/ {print $2}')
11622         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11623                awk '/ldlm_bl_callback/ {print $2}')
11624         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11625         sleep 5
11626         can2=$(do_facet mds1 \
11627                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11628                awk '/ldlm_cancel/ {print $2}')
11629         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11630                awk '/ldlm_bl_callback/ {print $2}')
11631         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11632         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11633         lru_resize_enable mdc
11634         lru_resize_enable osc
11635 }
11636 run_test 120f "Early Lock Cancel: rename test"
11637
11638 test_120g() {
11639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11640         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11641                 skip_env "no early lock cancel on server"
11642         remote_mds_nodsh && skip "remote MDS with nodsh"
11643
11644         lru_resize_disable mdc
11645         lru_resize_disable osc
11646         count=10000
11647         echo create $count files
11648         test_mkdir $DIR/$tdir
11649         cancel_lru_locks mdc
11650         cancel_lru_locks osc
11651         t0=$(date +%s)
11652
11653         can0=$(do_facet $SINGLEMDS \
11654                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11655                awk '/ldlm_cancel/ {print $2}')
11656         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11657                awk '/ldlm_bl_callback/ {print $2}')
11658         createmany -o $DIR/$tdir/f $count
11659         sync
11660         can1=$(do_facet $SINGLEMDS \
11661                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11662                awk '/ldlm_cancel/ {print $2}')
11663         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11664                awk '/ldlm_bl_callback/ {print $2}')
11665         t1=$(date +%s)
11666         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11667         echo rm $count files
11668         rm -r $DIR/$tdir
11669         sync
11670         can2=$(do_facet $SINGLEMDS \
11671                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11672                awk '/ldlm_cancel/ {print $2}')
11673         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11674                awk '/ldlm_bl_callback/ {print $2}')
11675         t2=$(date +%s)
11676         echo total: $count removes in $((t2-t1))
11677         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11678         sleep 2
11679         # wait for commitment of removal
11680         lru_resize_enable mdc
11681         lru_resize_enable osc
11682 }
11683 run_test 120g "Early Lock Cancel: performance test"
11684
11685 test_121() { #bug #10589
11686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11687
11688         rm -rf $DIR/$tfile
11689         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11690 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11691         lctl set_param fail_loc=0x310
11692         cancel_lru_locks osc > /dev/null
11693         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11694         lctl set_param fail_loc=0
11695         [[ $reads -eq $writes ]] ||
11696                 error "read $reads blocks, must be $writes blocks"
11697 }
11698 run_test 121 "read cancel race ========="
11699
11700 test_123a_base() { # was test 123, statahead(bug 11401)
11701         local lsx="$1"
11702
11703         SLOWOK=0
11704         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11705                 log "testing UP system. Performance may be lower than expected."
11706                 SLOWOK=1
11707         fi
11708
11709         rm -rf $DIR/$tdir
11710         test_mkdir $DIR/$tdir
11711         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11712         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11713         MULT=10
11714         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11715                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11716
11717                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11718                 lctl set_param -n llite.*.statahead_max 0
11719                 lctl get_param llite.*.statahead_max
11720                 cancel_lru_locks mdc
11721                 cancel_lru_locks osc
11722                 stime=$(date +%s)
11723                 time $lsx $DIR/$tdir | wc -l
11724                 etime=$(date +%s)
11725                 delta=$((etime - stime))
11726                 log "$lsx $i files without statahead: $delta sec"
11727                 lctl set_param llite.*.statahead_max=$max
11728
11729                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11730                         grep "statahead wrong:" | awk '{print $3}')
11731                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11732                 cancel_lru_locks mdc
11733                 cancel_lru_locks osc
11734                 stime=$(date +%s)
11735                 time $lsx $DIR/$tdir | wc -l
11736                 etime=$(date +%s)
11737                 delta_sa=$((etime - stime))
11738                 log "$lsx $i files with statahead: $delta_sa sec"
11739                 lctl get_param -n llite.*.statahead_stats
11740                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11741                         grep "statahead wrong:" | awk '{print $3}')
11742
11743                 [[ $swrong -lt $ewrong ]] &&
11744                         log "statahead was stopped, maybe too many locks held!"
11745                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11746
11747                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11748                         max=$(lctl get_param -n llite.*.statahead_max |
11749                                 head -n 1)
11750                         lctl set_param -n llite.*.statahead_max 0
11751                         lctl get_param llite.*.statahead_max
11752                         cancel_lru_locks mdc
11753                         cancel_lru_locks osc
11754                         stime=$(date +%s)
11755                         time $lsx $DIR/$tdir | wc -l
11756                         etime=$(date +%s)
11757                         delta=$((etime - stime))
11758                         log "$lsx $i files again without statahead: $delta sec"
11759                         lctl set_param llite.*.statahead_max=$max
11760                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11761                                 if [  $SLOWOK -eq 0 ]; then
11762                                         error "$lsx $i files is slower with statahead!"
11763                                 else
11764                                         log "$lsx $i files is slower with statahead!"
11765                                 fi
11766                                 break
11767                         fi
11768                 fi
11769
11770                 [ $delta -gt 20 ] && break
11771                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11772                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11773         done
11774         log "$lsx done"
11775
11776         stime=$(date +%s)
11777         rm -r $DIR/$tdir
11778         sync
11779         etime=$(date +%s)
11780         delta=$((etime - stime))
11781         log "rm -r $DIR/$tdir/: $delta seconds"
11782         log "rm done"
11783         lctl get_param -n llite.*.statahead_stats
11784 }
11785
11786 test_123aa() {
11787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11788
11789         test_123a_base "ls -l"
11790 }
11791 run_test 123aa "verify statahead work"
11792
11793 test_123ab() {
11794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11795
11796         statx_supported || skip_env "Test must be statx() syscall supported"
11797
11798         test_123a_base "$STATX -l"
11799 }
11800 run_test 123ab "verify statahead work by using statx"
11801
11802 test_123ac() {
11803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11804
11805         statx_supported || skip_env "Test must be statx() syscall supported"
11806
11807         local rpcs_before
11808         local rpcs_after
11809         local agl_before
11810         local agl_after
11811
11812         cancel_lru_locks $OSC
11813         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11814         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11815                 awk '/agl.total:/ {print $3}')
11816         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11817         test_123a_base "$STATX --cached=always -D"
11818         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11819                 awk '/agl.total:/ {print $3}')
11820         [ $agl_before -eq $agl_after ] ||
11821                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11822         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11823         [ $rpcs_after -eq $rpcs_before ] ||
11824                 error "$STATX should not send glimpse RPCs to $OSC"
11825 }
11826 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11827
11828 test_123b () { # statahead(bug 15027)
11829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11830
11831         test_mkdir $DIR/$tdir
11832         createmany -o $DIR/$tdir/$tfile-%d 1000
11833
11834         cancel_lru_locks mdc
11835         cancel_lru_locks osc
11836
11837 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11838         lctl set_param fail_loc=0x80000803
11839         ls -lR $DIR/$tdir > /dev/null
11840         log "ls done"
11841         lctl set_param fail_loc=0x0
11842         lctl get_param -n llite.*.statahead_stats
11843         rm -r $DIR/$tdir
11844         sync
11845
11846 }
11847 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11848
11849 test_123c() {
11850         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11851
11852         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11853         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11854         touch $DIR/$tdir.1/{1..3}
11855         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11856
11857         remount_client $MOUNT
11858
11859         $MULTIOP $DIR/$tdir.0 Q
11860
11861         # let statahead to complete
11862         ls -l $DIR/$tdir.0 > /dev/null
11863
11864         testid=$(echo $TESTNAME | tr '_' ' ')
11865         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11866                 error "statahead warning" || true
11867 }
11868 run_test 123c "Can not initialize inode warning on DNE statahead"
11869
11870 test_124a() {
11871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11872         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11873                 skip_env "no lru resize on server"
11874
11875         local NR=2000
11876
11877         test_mkdir $DIR/$tdir
11878
11879         log "create $NR files at $DIR/$tdir"
11880         createmany -o $DIR/$tdir/f $NR ||
11881                 error "failed to create $NR files in $DIR/$tdir"
11882
11883         cancel_lru_locks mdc
11884         ls -l $DIR/$tdir > /dev/null
11885
11886         local NSDIR=""
11887         local LRU_SIZE=0
11888         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11889                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11890                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11891                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11892                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11893                         log "NSDIR=$NSDIR"
11894                         log "NS=$(basename $NSDIR)"
11895                         break
11896                 fi
11897         done
11898
11899         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11900                 skip "Not enough cached locks created!"
11901         fi
11902         log "LRU=$LRU_SIZE"
11903
11904         local SLEEP=30
11905
11906         # We know that lru resize allows one client to hold $LIMIT locks
11907         # for 10h. After that locks begin to be killed by client.
11908         local MAX_HRS=10
11909         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11910         log "LIMIT=$LIMIT"
11911         if [ $LIMIT -lt $LRU_SIZE ]; then
11912                 skip "Limit is too small $LIMIT"
11913         fi
11914
11915         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11916         # killing locks. Some time was spent for creating locks. This means
11917         # that up to the moment of sleep finish we must have killed some of
11918         # them (10-100 locks). This depends on how fast ther were created.
11919         # Many of them were touched in almost the same moment and thus will
11920         # be killed in groups.
11921         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11922
11923         # Use $LRU_SIZE_B here to take into account real number of locks
11924         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11925         local LRU_SIZE_B=$LRU_SIZE
11926         log "LVF=$LVF"
11927         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11928         log "OLD_LVF=$OLD_LVF"
11929         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11930
11931         # Let's make sure that we really have some margin. Client checks
11932         # cached locks every 10 sec.
11933         SLEEP=$((SLEEP+20))
11934         log "Sleep ${SLEEP} sec"
11935         local SEC=0
11936         while ((SEC<$SLEEP)); do
11937                 echo -n "..."
11938                 sleep 5
11939                 SEC=$((SEC+5))
11940                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11941                 echo -n "$LRU_SIZE"
11942         done
11943         echo ""
11944         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11945         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11946
11947         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11948                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11949                 unlinkmany $DIR/$tdir/f $NR
11950                 return
11951         }
11952
11953         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11954         log "unlink $NR files at $DIR/$tdir"
11955         unlinkmany $DIR/$tdir/f $NR
11956 }
11957 run_test 124a "lru resize ======================================="
11958
11959 get_max_pool_limit()
11960 {
11961         local limit=$($LCTL get_param \
11962                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11963         local max=0
11964         for l in $limit; do
11965                 if [[ $l -gt $max ]]; then
11966                         max=$l
11967                 fi
11968         done
11969         echo $max
11970 }
11971
11972 test_124b() {
11973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11974         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11975                 skip_env "no lru resize on server"
11976
11977         LIMIT=$(get_max_pool_limit)
11978
11979         NR=$(($(default_lru_size)*20))
11980         if [[ $NR -gt $LIMIT ]]; then
11981                 log "Limit lock number by $LIMIT locks"
11982                 NR=$LIMIT
11983         fi
11984
11985         IFree=$(mdsrate_inodes_available)
11986         if [ $IFree -lt $NR ]; then
11987                 log "Limit lock number by $IFree inodes"
11988                 NR=$IFree
11989         fi
11990
11991         lru_resize_disable mdc
11992         test_mkdir -p $DIR/$tdir/disable_lru_resize
11993
11994         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11995         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11996         cancel_lru_locks mdc
11997         stime=`date +%s`
11998         PID=""
11999         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12000         PID="$PID $!"
12001         sleep 2
12002         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12003         PID="$PID $!"
12004         sleep 2
12005         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12006         PID="$PID $!"
12007         wait $PID
12008         etime=`date +%s`
12009         nolruresize_delta=$((etime-stime))
12010         log "ls -la time: $nolruresize_delta seconds"
12011         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12012         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12013
12014         lru_resize_enable mdc
12015         test_mkdir -p $DIR/$tdir/enable_lru_resize
12016
12017         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12018         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12019         cancel_lru_locks mdc
12020         stime=`date +%s`
12021         PID=""
12022         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12023         PID="$PID $!"
12024         sleep 2
12025         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12026         PID="$PID $!"
12027         sleep 2
12028         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12029         PID="$PID $!"
12030         wait $PID
12031         etime=`date +%s`
12032         lruresize_delta=$((etime-stime))
12033         log "ls -la time: $lruresize_delta seconds"
12034         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12035
12036         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12037                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12038         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12039                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12040         else
12041                 log "lru resize performs the same with no lru resize"
12042         fi
12043         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12044 }
12045 run_test 124b "lru resize (performance test) ======================="
12046
12047 test_124c() {
12048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12049         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12050                 skip_env "no lru resize on server"
12051
12052         # cache ununsed locks on client
12053         local nr=100
12054         cancel_lru_locks mdc
12055         test_mkdir $DIR/$tdir
12056         createmany -o $DIR/$tdir/f $nr ||
12057                 error "failed to create $nr files in $DIR/$tdir"
12058         ls -l $DIR/$tdir > /dev/null
12059
12060         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12061         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12062         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12063         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12064         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12065
12066         # set lru_max_age to 1 sec
12067         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12068         echo "sleep $((recalc_p * 2)) seconds..."
12069         sleep $((recalc_p * 2))
12070
12071         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12072         # restore lru_max_age
12073         $LCTL set_param -n $nsdir.lru_max_age $max_age
12074         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12075         unlinkmany $DIR/$tdir/f $nr
12076 }
12077 run_test 124c "LRUR cancel very aged locks"
12078
12079 test_124d() {
12080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12081         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12082                 skip_env "no lru resize on server"
12083
12084         # cache ununsed locks on client
12085         local nr=100
12086
12087         lru_resize_disable mdc
12088         stack_trap "lru_resize_enable mdc" EXIT
12089
12090         cancel_lru_locks mdc
12091
12092         # asynchronous object destroy at MDT could cause bl ast to client
12093         test_mkdir $DIR/$tdir
12094         createmany -o $DIR/$tdir/f $nr ||
12095                 error "failed to create $nr files in $DIR/$tdir"
12096         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12097
12098         ls -l $DIR/$tdir > /dev/null
12099
12100         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12101         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12102         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12103         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12104
12105         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12106
12107         # set lru_max_age to 1 sec
12108         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12109         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12110
12111         echo "sleep $((recalc_p * 2)) seconds..."
12112         sleep $((recalc_p * 2))
12113
12114         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12115
12116         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12117 }
12118 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12119
12120 test_125() { # 13358
12121         $LCTL get_param -n llite.*.client_type | grep -q local ||
12122                 skip "must run as local client"
12123         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12124                 skip_env "must have acl enabled"
12125         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12126
12127         test_mkdir $DIR/$tdir
12128         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12129         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12130         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12131 }
12132 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12133
12134 test_126() { # bug 12829/13455
12135         $GSS && skip_env "must run as gss disabled"
12136         $LCTL get_param -n llite.*.client_type | grep -q local ||
12137                 skip "must run as local client"
12138         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12139
12140         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12141         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12142         rm -f $DIR/$tfile
12143         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12144 }
12145 run_test 126 "check that the fsgid provided by the client is taken into account"
12146
12147 test_127a() { # bug 15521
12148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12149         local name count samp unit min max sum sumsq
12150
12151         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12152         echo "stats before reset"
12153         $LCTL get_param osc.*.stats
12154         $LCTL set_param osc.*.stats=0
12155         local fsize=$((2048 * 1024))
12156
12157         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12158         cancel_lru_locks osc
12159         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12160
12161         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12162         stack_trap "rm -f $TMP/$tfile.tmp"
12163         while read name count samp unit min max sum sumsq; do
12164                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12165                 [ ! $min ] && error "Missing min value for $name proc entry"
12166                 eval $name=$count || error "Wrong proc format"
12167
12168                 case $name in
12169                 read_bytes|write_bytes)
12170                         [[ "$unit" =~ "bytes" ]] ||
12171                                 error "unit is not 'bytes': $unit"
12172                         (( $min >= 4096 )) || error "min is too small: $min"
12173                         (( $min <= $fsize )) || error "min is too big: $min"
12174                         (( $max >= 4096 )) || error "max is too small: $max"
12175                         (( $max <= $fsize )) || error "max is too big: $max"
12176                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12177                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12178                                 error "sumsquare is too small: $sumsq"
12179                         (( $sumsq <= $fsize * $fsize )) ||
12180                                 error "sumsquare is too big: $sumsq"
12181                         ;;
12182                 ost_read|ost_write)
12183                         [[ "$unit" =~ "usec" ]] ||
12184                                 error "unit is not 'usec': $unit"
12185                         ;;
12186                 *)      ;;
12187                 esac
12188         done < $DIR/$tfile.tmp
12189
12190         #check that we actually got some stats
12191         [ "$read_bytes" ] || error "Missing read_bytes stats"
12192         [ "$write_bytes" ] || error "Missing write_bytes stats"
12193         [ "$read_bytes" != 0 ] || error "no read done"
12194         [ "$write_bytes" != 0 ] || error "no write done"
12195 }
12196 run_test 127a "verify the client stats are sane"
12197
12198 test_127b() { # bug LU-333
12199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12200         local name count samp unit min max sum sumsq
12201
12202         echo "stats before reset"
12203         $LCTL get_param llite.*.stats
12204         $LCTL set_param llite.*.stats=0
12205
12206         # perform 2 reads and writes so MAX is different from SUM.
12207         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12208         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12209         cancel_lru_locks osc
12210         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12211         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12212
12213         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12214         stack_trap "rm -f $TMP/$tfile.tmp"
12215         while read name count samp unit min max sum sumsq; do
12216                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12217                 eval $name=$count || error "Wrong proc format"
12218
12219                 case $name in
12220                 read_bytes|write_bytes)
12221                         [[ "$unit" =~ "bytes" ]] ||
12222                                 error "unit is not 'bytes': $unit"
12223                         (( $count == 2 )) || error "count is not 2: $count"
12224                         (( $min == $PAGE_SIZE )) ||
12225                                 error "min is not $PAGE_SIZE: $min"
12226                         (( $max == $PAGE_SIZE )) ||
12227                                 error "max is not $PAGE_SIZE: $max"
12228                         (( $sum == $PAGE_SIZE * 2 )) ||
12229                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12230                         ;;
12231                 read|write)
12232                         [[ "$unit" =~ "usec" ]] ||
12233                                 error "unit is not 'usec': $unit"
12234                         ;;
12235                 *)      ;;
12236                 esac
12237         done < $TMP/$tfile.tmp
12238
12239         #check that we actually got some stats
12240         [ "$read_bytes" ] || error "Missing read_bytes stats"
12241         [ "$write_bytes" ] || error "Missing write_bytes stats"
12242         [ "$read_bytes" != 0 ] || error "no read done"
12243         [ "$write_bytes" != 0 ] || error "no write done"
12244 }
12245 run_test 127b "verify the llite client stats are sane"
12246
12247 test_127c() { # LU-12394
12248         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12249         local size
12250         local bsize
12251         local reads
12252         local writes
12253         local count
12254
12255         $LCTL set_param llite.*.extents_stats=1
12256         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12257
12258         # Use two stripes so there is enough space in default config
12259         $LFS setstripe -c 2 $DIR/$tfile
12260
12261         # Extent stats start at 0-4K and go in power of two buckets
12262         # LL_HIST_START = 12 --> 2^12 = 4K
12263         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12264         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12265         # small configs
12266         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12267                 do
12268                 # Write and read, 2x each, second time at a non-zero offset
12269                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12270                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12271                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12272                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12273                 rm -f $DIR/$tfile
12274         done
12275
12276         $LCTL get_param llite.*.extents_stats
12277
12278         count=2
12279         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12280                 do
12281                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12282                                 grep -m 1 $bsize)
12283                 reads=$(echo $bucket | awk '{print $5}')
12284                 writes=$(echo $bucket | awk '{print $9}')
12285                 [ "$reads" -eq $count ] ||
12286                         error "$reads reads in < $bsize bucket, expect $count"
12287                 [ "$writes" -eq $count ] ||
12288                         error "$writes writes in < $bsize bucket, expect $count"
12289         done
12290
12291         # Test mmap write and read
12292         $LCTL set_param llite.*.extents_stats=c
12293         size=512
12294         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12295         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12296         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12297
12298         $LCTL get_param llite.*.extents_stats
12299
12300         count=$(((size*1024) / PAGE_SIZE))
12301
12302         bsize=$((2 * PAGE_SIZE / 1024))K
12303
12304         bucket=$($LCTL get_param -n llite.*.extents_stats |
12305                         grep -m 1 $bsize)
12306         reads=$(echo $bucket | awk '{print $5}')
12307         writes=$(echo $bucket | awk '{print $9}')
12308         # mmap writes fault in the page first, creating an additonal read
12309         [ "$reads" -eq $((2 * count)) ] ||
12310                 error "$reads reads in < $bsize bucket, expect $count"
12311         [ "$writes" -eq $count ] ||
12312                 error "$writes writes in < $bsize bucket, expect $count"
12313 }
12314 run_test 127c "test llite extent stats with regular & mmap i/o"
12315
12316 test_128() { # bug 15212
12317         touch $DIR/$tfile
12318         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12319                 find $DIR/$tfile
12320                 find $DIR/$tfile
12321         EOF
12322
12323         result=$(grep error $TMP/$tfile.log)
12324         rm -f $DIR/$tfile $TMP/$tfile.log
12325         [ -z "$result" ] ||
12326                 error "consecutive find's under interactive lfs failed"
12327 }
12328 run_test 128 "interactive lfs for 2 consecutive find's"
12329
12330 set_dir_limits () {
12331         local mntdev
12332         local canondev
12333         local node
12334
12335         local ldproc=/proc/fs/ldiskfs
12336         local facets=$(get_facets MDS)
12337
12338         for facet in ${facets//,/ }; do
12339                 canondev=$(ldiskfs_canon \
12340                            *.$(convert_facet2label $facet).mntdev $facet)
12341                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12342                         ldproc=/sys/fs/ldiskfs
12343                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12344                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12345         done
12346 }
12347
12348 check_mds_dmesg() {
12349         local facets=$(get_facets MDS)
12350         for facet in ${facets//,/ }; do
12351                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12352         done
12353         return 1
12354 }
12355
12356 test_129() {
12357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12358         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12359                 skip "Need MDS version with at least 2.5.56"
12360         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12361                 skip_env "ldiskfs only test"
12362         fi
12363         remote_mds_nodsh && skip "remote MDS with nodsh"
12364
12365         local ENOSPC=28
12366         local has_warning=false
12367
12368         rm -rf $DIR/$tdir
12369         mkdir -p $DIR/$tdir
12370
12371         # block size of mds1
12372         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12373         set_dir_limits $maxsize $((maxsize * 6 / 8))
12374         stack_trap "set_dir_limits 0 0"
12375         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12376         local dirsize=$(stat -c%s "$DIR/$tdir")
12377         local nfiles=0
12378         while (( $dirsize <= $maxsize )); do
12379                 $MCREATE $DIR/$tdir/file_base_$nfiles
12380                 rc=$?
12381                 # check two errors:
12382                 # ENOSPC for ext4 max_dir_size, which has been used since
12383                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12384                 if (( rc == ENOSPC )); then
12385                         set_dir_limits 0 0
12386                         echo "rc=$rc returned as expected after $nfiles files"
12387
12388                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12389                                 error "create failed w/o dir size limit"
12390
12391                         # messages may be rate limited if test is run repeatedly
12392                         check_mds_dmesg '"is approaching max"' ||
12393                                 echo "warning message should be output"
12394                         check_mds_dmesg '"has reached max"' ||
12395                                 echo "reached message should be output"
12396
12397                         dirsize=$(stat -c%s "$DIR/$tdir")
12398
12399                         [[ $dirsize -ge $maxsize ]] && return 0
12400                         error "dirsize $dirsize < $maxsize after $nfiles files"
12401                 elif (( rc != 0 )); then
12402                         break
12403                 fi
12404                 nfiles=$((nfiles + 1))
12405                 dirsize=$(stat -c%s "$DIR/$tdir")
12406         done
12407
12408         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12409 }
12410 run_test 129 "test directory size limit ========================"
12411
12412 OLDIFS="$IFS"
12413 cleanup_130() {
12414         trap 0
12415         IFS="$OLDIFS"
12416 }
12417
12418 test_130a() {
12419         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12420         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12421
12422         trap cleanup_130 EXIT RETURN
12423
12424         local fm_file=$DIR/$tfile
12425         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12426         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12427                 error "dd failed for $fm_file"
12428
12429         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12430         filefrag -ves $fm_file
12431         RC=$?
12432         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12433                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12434         [ $RC != 0 ] && error "filefrag $fm_file failed"
12435
12436         filefrag_op=$(filefrag -ve -k $fm_file |
12437                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12438         lun=$($LFS getstripe -i $fm_file)
12439
12440         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12441         IFS=$'\n'
12442         tot_len=0
12443         for line in $filefrag_op
12444         do
12445                 frag_lun=`echo $line | cut -d: -f5`
12446                 ext_len=`echo $line | cut -d: -f4`
12447                 if (( $frag_lun != $lun )); then
12448                         cleanup_130
12449                         error "FIEMAP on 1-stripe file($fm_file) failed"
12450                         return
12451                 fi
12452                 (( tot_len += ext_len ))
12453         done
12454
12455         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12456                 cleanup_130
12457                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12458                 return
12459         fi
12460
12461         cleanup_130
12462
12463         echo "FIEMAP on single striped file succeeded"
12464 }
12465 run_test 130a "FIEMAP (1-stripe file)"
12466
12467 test_130b() {
12468         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12469
12470         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12471         [ -n "$filefrag_op" ] && skip_env "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 $OSTCOUNT $fm_file ||
12477                         error "setstripe on $fm_file"
12478         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12479                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12480
12481         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12482                 error "dd failed on $fm_file"
12483
12484         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12485         filefrag_op=$(filefrag -ve -k $fm_file |
12486                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12487
12488         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12489                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12490
12491         IFS=$'\n'
12492         tot_len=0
12493         num_luns=1
12494         for line in $filefrag_op
12495         do
12496                 frag_lun=$(echo $line | cut -d: -f5 |
12497                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12498                 ext_len=$(echo $line | cut -d: -f4)
12499                 if (( $frag_lun != $last_lun )); then
12500                         if (( tot_len != 1024 )); then
12501                                 cleanup_130
12502                                 error "FIEMAP on $fm_file failed; returned " \
12503                                 "len $tot_len for OST $last_lun instead of 1024"
12504                                 return
12505                         else
12506                                 (( num_luns += 1 ))
12507                                 tot_len=0
12508                         fi
12509                 fi
12510                 (( tot_len += ext_len ))
12511                 last_lun=$frag_lun
12512         done
12513         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12514                 cleanup_130
12515                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12516                         "luns or wrong len for OST $last_lun"
12517                 return
12518         fi
12519
12520         cleanup_130
12521
12522         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12523 }
12524 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12525
12526 test_130c() {
12527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12528
12529         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12530         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12531
12532         trap cleanup_130 EXIT RETURN
12533
12534         local fm_file=$DIR/$tfile
12535         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12536         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12537                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12538
12539         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12540                         error "dd failed on $fm_file"
12541
12542         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12543         filefrag_op=$(filefrag -ve -k $fm_file |
12544                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12545
12546         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12547                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12548
12549         IFS=$'\n'
12550         tot_len=0
12551         num_luns=1
12552         for line in $filefrag_op
12553         do
12554                 frag_lun=$(echo $line | cut -d: -f5 |
12555                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12556                 ext_len=$(echo $line | cut -d: -f4)
12557                 if (( $frag_lun != $last_lun )); then
12558                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12559                         if (( logical != 512 )); then
12560                                 cleanup_130
12561                                 error "FIEMAP on $fm_file failed; returned " \
12562                                 "logical start for lun $logical instead of 512"
12563                                 return
12564                         fi
12565                         if (( tot_len != 512 )); then
12566                                 cleanup_130
12567                                 error "FIEMAP on $fm_file failed; returned " \
12568                                 "len $tot_len for OST $last_lun instead of 1024"
12569                                 return
12570                         else
12571                                 (( num_luns += 1 ))
12572                                 tot_len=0
12573                         fi
12574                 fi
12575                 (( tot_len += ext_len ))
12576                 last_lun=$frag_lun
12577         done
12578         if (( num_luns != 2 || tot_len != 512 )); then
12579                 cleanup_130
12580                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12581                         "luns or wrong len for OST $last_lun"
12582                 return
12583         fi
12584
12585         cleanup_130
12586
12587         echo "FIEMAP on 2-stripe file with hole succeeded"
12588 }
12589 run_test 130c "FIEMAP (2-stripe file with hole)"
12590
12591 test_130d() {
12592         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12593
12594         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12595         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12596
12597         trap cleanup_130 EXIT RETURN
12598
12599         local fm_file=$DIR/$tfile
12600         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12601                         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         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12606         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12607                 error "dd failed on $fm_file"
12608
12609         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12610         filefrag_op=$(filefrag -ve -k $fm_file |
12611                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12612
12613         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12614                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12615
12616         IFS=$'\n'
12617         tot_len=0
12618         num_luns=1
12619         for line in $filefrag_op
12620         do
12621                 frag_lun=$(echo $line | cut -d: -f5 |
12622                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12623                 ext_len=$(echo $line | cut -d: -f4)
12624                 if (( $frag_lun != $last_lun )); then
12625                         if (( tot_len != 1024 )); then
12626                                 cleanup_130
12627                                 error "FIEMAP on $fm_file failed; returned " \
12628                                 "len $tot_len for OST $last_lun instead of 1024"
12629                                 return
12630                         else
12631                                 (( num_luns += 1 ))
12632                                 tot_len=0
12633                         fi
12634                 fi
12635                 (( tot_len += ext_len ))
12636                 last_lun=$frag_lun
12637         done
12638         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12639                 cleanup_130
12640                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12641                         "luns or wrong len for OST $last_lun"
12642                 return
12643         fi
12644
12645         cleanup_130
12646
12647         echo "FIEMAP on N-stripe file succeeded"
12648 }
12649 run_test 130d "FIEMAP (N-stripe file)"
12650
12651 test_130e() {
12652         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12653
12654         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12655         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12656
12657         trap cleanup_130 EXIT RETURN
12658
12659         local fm_file=$DIR/$tfile
12660         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12661
12662         NUM_BLKS=512
12663         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12664         for ((i = 0; i < $NUM_BLKS; i++)); do
12665                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12666                         conv=notrunc > /dev/null 2>&1
12667         done
12668
12669         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12670         filefrag_op=$(filefrag -ve -k $fm_file |
12671                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12672
12673         last_lun=$(echo $filefrag_op | cut -d: -f5)
12674
12675         IFS=$'\n'
12676         tot_len=0
12677         num_luns=1
12678         for line in $filefrag_op; do
12679                 frag_lun=$(echo $line | cut -d: -f5)
12680                 ext_len=$(echo $line | cut -d: -f4)
12681                 if [[ "$frag_lun" != "$last_lun" ]]; then
12682                         if (( tot_len != $EXPECTED_LEN )); then
12683                                 cleanup_130
12684                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12685                         else
12686                                 (( num_luns += 1 ))
12687                                 tot_len=0
12688                         fi
12689                 fi
12690                 (( tot_len += ext_len ))
12691                 last_lun=$frag_lun
12692         done
12693         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12694                 cleanup_130
12695                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12696         fi
12697
12698         echo "FIEMAP with continuation calls succeeded"
12699 }
12700 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12701
12702 test_130f() {
12703         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12704         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12705
12706         local fm_file=$DIR/$tfile
12707         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12708                 error "multiop create with lov_delay_create on $fm_file"
12709
12710         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12711         filefrag_extents=$(filefrag -vek $fm_file |
12712                            awk '/extents? found/ { print $2 }')
12713         if [[ "$filefrag_extents" != "0" ]]; then
12714                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12715         fi
12716
12717         rm -f $fm_file
12718 }
12719 run_test 130f "FIEMAP (unstriped file)"
12720
12721 test_130g() {
12722         local file=$DIR/$tfile
12723         local nr=$((OSTCOUNT * 100))
12724
12725         $LFS setstripe -C $nr $file ||
12726                 error "failed to setstripe -C $nr $file"
12727
12728         dd if=/dev/zero of=$file count=$nr bs=1M
12729         sync
12730         nr=$($LFS getstripe -c $file)
12731
12732         local extents=$(filefrag -v $file |
12733                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12734
12735         echo "filefrag list $extents extents in file with stripecount $nr"
12736         if (( extents < nr )); then
12737                 $LFS getstripe $file
12738                 filefrag -v $file
12739                 error "filefrag printed $extents < $nr extents"
12740         fi
12741
12742         rm -f $file
12743 }
12744 run_test 130g "FIEMAP (overstripe file)"
12745
12746 # Test for writev/readv
12747 test_131a() {
12748         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12749                 error "writev test failed"
12750         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12751                 error "readv failed"
12752         rm -f $DIR/$tfile
12753 }
12754 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12755
12756 test_131b() {
12757         local fsize=$((524288 + 1048576 + 1572864))
12758         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12759                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12760                         error "append writev test failed"
12761
12762         ((fsize += 1572864 + 1048576))
12763         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12764                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12765                         error "append writev test failed"
12766         rm -f $DIR/$tfile
12767 }
12768 run_test 131b "test append writev"
12769
12770 test_131c() {
12771         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12772         error "NOT PASS"
12773 }
12774 run_test 131c "test read/write on file w/o objects"
12775
12776 test_131d() {
12777         rwv -f $DIR/$tfile -w -n 1 1572864
12778         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12779         if [ "$NOB" != 1572864 ]; then
12780                 error "Short read filed: read $NOB bytes instead of 1572864"
12781         fi
12782         rm -f $DIR/$tfile
12783 }
12784 run_test 131d "test short read"
12785
12786 test_131e() {
12787         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12788         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12789         error "read hitting hole failed"
12790         rm -f $DIR/$tfile
12791 }
12792 run_test 131e "test read hitting hole"
12793
12794 check_stats() {
12795         local facet=$1
12796         local op=$2
12797         local want=${3:-0}
12798         local res
12799
12800         case $facet in
12801         mds*) res=$(do_facet $facet \
12802                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12803                  ;;
12804         ost*) res=$(do_facet $facet \
12805                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12806                  ;;
12807         *) error "Wrong facet '$facet'" ;;
12808         esac
12809         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12810         # if the argument $3 is zero, it means any stat increment is ok.
12811         if [[ $want -gt 0 ]]; then
12812                 local count=$(echo $res | awk '{ print $2 }')
12813                 [[ $count -ne $want ]] &&
12814                         error "The $op counter on $facet is $count, not $want"
12815         fi
12816 }
12817
12818 test_133a() {
12819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12820         remote_ost_nodsh && skip "remote OST with nodsh"
12821         remote_mds_nodsh && skip "remote MDS with nodsh"
12822         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12823                 skip_env "MDS doesn't support rename stats"
12824
12825         local testdir=$DIR/${tdir}/stats_testdir
12826
12827         mkdir -p $DIR/${tdir}
12828
12829         # clear stats.
12830         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12831         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12832
12833         # verify mdt stats first.
12834         mkdir ${testdir} || error "mkdir failed"
12835         check_stats $SINGLEMDS "mkdir" 1
12836         touch ${testdir}/${tfile} || error "touch failed"
12837         check_stats $SINGLEMDS "open" 1
12838         check_stats $SINGLEMDS "close" 1
12839         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12840                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12841                 check_stats $SINGLEMDS "mknod" 2
12842         }
12843         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12844         check_stats $SINGLEMDS "unlink" 1
12845         rm -f ${testdir}/${tfile} || error "file remove failed"
12846         check_stats $SINGLEMDS "unlink" 2
12847
12848         # remove working dir and check mdt stats again.
12849         rmdir ${testdir} || error "rmdir failed"
12850         check_stats $SINGLEMDS "rmdir" 1
12851
12852         local testdir1=$DIR/${tdir}/stats_testdir1
12853         mkdir -p ${testdir}
12854         mkdir -p ${testdir1}
12855         touch ${testdir1}/test1
12856         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12857         check_stats $SINGLEMDS "crossdir_rename" 1
12858
12859         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12860         check_stats $SINGLEMDS "samedir_rename" 1
12861
12862         rm -rf $DIR/${tdir}
12863 }
12864 run_test 133a "Verifying MDT stats ========================================"
12865
12866 test_133b() {
12867         local res
12868
12869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12870         remote_ost_nodsh && skip "remote OST with nodsh"
12871         remote_mds_nodsh && skip "remote MDS with nodsh"
12872
12873         local testdir=$DIR/${tdir}/stats_testdir
12874
12875         mkdir -p ${testdir} || error "mkdir failed"
12876         touch ${testdir}/${tfile} || error "touch failed"
12877         cancel_lru_locks mdc
12878
12879         # clear stats.
12880         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12881         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12882
12883         # extra mdt stats verification.
12884         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12885         check_stats $SINGLEMDS "setattr" 1
12886         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12887         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12888         then            # LU-1740
12889                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12890                 check_stats $SINGLEMDS "getattr" 1
12891         fi
12892         rm -rf $DIR/${tdir}
12893
12894         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12895         # so the check below is not reliable
12896         [ $MDSCOUNT -eq 1 ] || return 0
12897
12898         # Sleep to avoid a cached response.
12899         #define OBD_STATFS_CACHE_SECONDS 1
12900         sleep 2
12901         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12902         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12903         $LFS df || error "lfs failed"
12904         check_stats $SINGLEMDS "statfs" 1
12905
12906         # check aggregated statfs (LU-10018)
12907         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12908                 return 0
12909         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12910                 return 0
12911         sleep 2
12912         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12913         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12914         df $DIR
12915         check_stats $SINGLEMDS "statfs" 1
12916
12917         # We want to check that the client didn't send OST_STATFS to
12918         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12919         # extra care is needed here.
12920         if remote_mds; then
12921                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12922                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12923
12924                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12925                 [ "$res" ] && error "OST got STATFS"
12926         fi
12927
12928         return 0
12929 }
12930 run_test 133b "Verifying extra MDT stats =================================="
12931
12932 test_133c() {
12933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12934         remote_ost_nodsh && skip "remote OST with nodsh"
12935         remote_mds_nodsh && skip "remote MDS with nodsh"
12936
12937         local testdir=$DIR/$tdir/stats_testdir
12938
12939         test_mkdir -p $testdir
12940
12941         # verify obdfilter stats.
12942         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12943         sync
12944         cancel_lru_locks osc
12945         wait_delete_completed
12946
12947         # clear stats.
12948         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12949         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12950
12951         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12952                 error "dd failed"
12953         sync
12954         cancel_lru_locks osc
12955         check_stats ost1 "write" 1
12956
12957         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12958         check_stats ost1 "read" 1
12959
12960         > $testdir/$tfile || error "truncate failed"
12961         check_stats ost1 "punch" 1
12962
12963         rm -f $testdir/$tfile || error "file remove failed"
12964         wait_delete_completed
12965         check_stats ost1 "destroy" 1
12966
12967         rm -rf $DIR/$tdir
12968 }
12969 run_test 133c "Verifying OST stats ========================================"
12970
12971 order_2() {
12972         local value=$1
12973         local orig=$value
12974         local order=1
12975
12976         while [ $value -ge 2 ]; do
12977                 order=$((order*2))
12978                 value=$((value/2))
12979         done
12980
12981         if [ $orig -gt $order ]; then
12982                 order=$((order*2))
12983         fi
12984         echo $order
12985 }
12986
12987 size_in_KMGT() {
12988     local value=$1
12989     local size=('K' 'M' 'G' 'T');
12990     local i=0
12991     local size_string=$value
12992
12993     while [ $value -ge 1024 ]; do
12994         if [ $i -gt 3 ]; then
12995             #T is the biggest unit we get here, if that is bigger,
12996             #just return XXXT
12997             size_string=${value}T
12998             break
12999         fi
13000         value=$((value >> 10))
13001         if [ $value -lt 1024 ]; then
13002             size_string=${value}${size[$i]}
13003             break
13004         fi
13005         i=$((i + 1))
13006     done
13007
13008     echo $size_string
13009 }
13010
13011 get_rename_size() {
13012         local size=$1
13013         local context=${2:-.}
13014         local sample=$(do_facet $SINGLEMDS $LCTL \
13015                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13016                 grep -A1 $context |
13017                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13018         echo $sample
13019 }
13020
13021 test_133d() {
13022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13023         remote_ost_nodsh && skip "remote OST with nodsh"
13024         remote_mds_nodsh && skip "remote MDS with nodsh"
13025         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13026                 skip_env "MDS doesn't support rename stats"
13027
13028         local testdir1=$DIR/${tdir}/stats_testdir1
13029         local testdir2=$DIR/${tdir}/stats_testdir2
13030         mkdir -p $DIR/${tdir}
13031
13032         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13033
13034         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13035         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13036
13037         createmany -o $testdir1/test 512 || error "createmany failed"
13038
13039         # check samedir rename size
13040         mv ${testdir1}/test0 ${testdir1}/test_0
13041
13042         local testdir1_size=$(ls -l $DIR/${tdir} |
13043                 awk '/stats_testdir1/ {print $5}')
13044         local testdir2_size=$(ls -l $DIR/${tdir} |
13045                 awk '/stats_testdir2/ {print $5}')
13046
13047         testdir1_size=$(order_2 $testdir1_size)
13048         testdir2_size=$(order_2 $testdir2_size)
13049
13050         testdir1_size=$(size_in_KMGT $testdir1_size)
13051         testdir2_size=$(size_in_KMGT $testdir2_size)
13052
13053         echo "source rename dir size: ${testdir1_size}"
13054         echo "target rename dir size: ${testdir2_size}"
13055
13056         local cmd="do_facet $SINGLEMDS $LCTL "
13057         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13058
13059         eval $cmd || error "$cmd failed"
13060         local samedir=$($cmd | grep 'same_dir')
13061         local same_sample=$(get_rename_size $testdir1_size)
13062         [ -z "$samedir" ] && error "samedir_rename_size count error"
13063         [[ $same_sample -eq 1 ]] ||
13064                 error "samedir_rename_size error $same_sample"
13065         echo "Check same dir rename stats success"
13066
13067         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13068
13069         # check crossdir rename size
13070         mv ${testdir1}/test_0 ${testdir2}/test_0
13071
13072         testdir1_size=$(ls -l $DIR/${tdir} |
13073                 awk '/stats_testdir1/ {print $5}')
13074         testdir2_size=$(ls -l $DIR/${tdir} |
13075                 awk '/stats_testdir2/ {print $5}')
13076
13077         testdir1_size=$(order_2 $testdir1_size)
13078         testdir2_size=$(order_2 $testdir2_size)
13079
13080         testdir1_size=$(size_in_KMGT $testdir1_size)
13081         testdir2_size=$(size_in_KMGT $testdir2_size)
13082
13083         echo "source rename dir size: ${testdir1_size}"
13084         echo "target rename dir size: ${testdir2_size}"
13085
13086         eval $cmd || error "$cmd failed"
13087         local crossdir=$($cmd | grep 'crossdir')
13088         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13089         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13090         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13091         [[ $src_sample -eq 1 ]] ||
13092                 error "crossdir_rename_size error $src_sample"
13093         [[ $tgt_sample -eq 1 ]] ||
13094                 error "crossdir_rename_size error $tgt_sample"
13095         echo "Check cross dir rename stats success"
13096         rm -rf $DIR/${tdir}
13097 }
13098 run_test 133d "Verifying rename_stats ========================================"
13099
13100 test_133e() {
13101         remote_mds_nodsh && skip "remote MDS with nodsh"
13102         remote_ost_nodsh && skip "remote OST with nodsh"
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104
13105         local testdir=$DIR/${tdir}/stats_testdir
13106         local ctr f0 f1 bs=32768 count=42 sum
13107
13108         mkdir -p ${testdir} || error "mkdir failed"
13109
13110         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13111
13112         for ctr in {write,read}_bytes; do
13113                 sync
13114                 cancel_lru_locks osc
13115
13116                 do_facet ost1 $LCTL set_param -n \
13117                         "obdfilter.*.exports.clear=clear"
13118
13119                 if [ $ctr = write_bytes ]; then
13120                         f0=/dev/zero
13121                         f1=${testdir}/${tfile}
13122                 else
13123                         f0=${testdir}/${tfile}
13124                         f1=/dev/null
13125                 fi
13126
13127                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13128                         error "dd failed"
13129                 sync
13130                 cancel_lru_locks osc
13131
13132                 sum=$(do_facet ost1 $LCTL get_param \
13133                         "obdfilter.*.exports.*.stats" |
13134                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13135                                 $1 == ctr { sum += $7 }
13136                                 END { printf("%0.0f", sum) }')
13137
13138                 if ((sum != bs * count)); then
13139                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13140                 fi
13141         done
13142
13143         rm -rf $DIR/${tdir}
13144 }
13145 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13146
13147 test_133f() {
13148         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13149                 skip "too old lustre for get_param -R ($facet_ver)"
13150
13151         # verifying readability.
13152         $LCTL get_param -R '*' &> /dev/null
13153
13154         # Verifing writability with badarea_io.
13155         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13156                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13157                 error "client badarea_io failed"
13158
13159         # remount the FS in case writes/reads /proc break the FS
13160         cleanup || error "failed to unmount"
13161         setup || error "failed to setup"
13162 }
13163 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13164
13165 test_133g() {
13166         remote_mds_nodsh && skip "remote MDS with nodsh"
13167         remote_ost_nodsh && skip "remote OST with nodsh"
13168
13169         local facet
13170         for facet in mds1 ost1; do
13171                 local facet_ver=$(lustre_version_code $facet)
13172                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13173                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13174                 else
13175                         log "$facet: too old lustre for get_param -R"
13176                 fi
13177                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13178                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13179                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13180                                 xargs badarea_io" ||
13181                                         error "$facet badarea_io failed"
13182                 else
13183                         skip_noexit "$facet: too old lustre for get_param -R"
13184                 fi
13185         done
13186
13187         # remount the FS in case writes/reads /proc break the FS
13188         cleanup || error "failed to unmount"
13189         setup || error "failed to setup"
13190 }
13191 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13192
13193 test_133h() {
13194         remote_mds_nodsh && skip "remote MDS with nodsh"
13195         remote_ost_nodsh && skip "remote OST with nodsh"
13196         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13197                 skip "Need MDS version at least 2.9.54"
13198
13199         local facet
13200         for facet in client mds1 ost1; do
13201                 # Get the list of files that are missing the terminating newline
13202                 local plist=$(do_facet $facet
13203                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13204                 local ent
13205                 for ent in $plist; do
13206                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13207                                 awk -v FS='\v' -v RS='\v\v' \
13208                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13209                                         print FILENAME}'" 2>/dev/null)
13210                         [ -z $missing ] || {
13211                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13212                                 error "file does not end with newline: $facet-$ent"
13213                         }
13214                 done
13215         done
13216 }
13217 run_test 133h "Proc files should end with newlines"
13218
13219 test_134a() {
13220         remote_mds_nodsh && skip "remote MDS with nodsh"
13221         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13222                 skip "Need MDS version at least 2.7.54"
13223
13224         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13225         cancel_lru_locks mdc
13226
13227         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13228         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13229         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13230
13231         local nr=1000
13232         createmany -o $DIR/$tdir/f $nr ||
13233                 error "failed to create $nr files in $DIR/$tdir"
13234         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13235
13236         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13237         do_facet mds1 $LCTL set_param fail_loc=0x327
13238         do_facet mds1 $LCTL set_param fail_val=500
13239         touch $DIR/$tdir/m
13240
13241         echo "sleep 10 seconds ..."
13242         sleep 10
13243         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13244
13245         do_facet mds1 $LCTL set_param fail_loc=0
13246         do_facet mds1 $LCTL set_param fail_val=0
13247         [ $lck_cnt -lt $unused ] ||
13248                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13249
13250         rm $DIR/$tdir/m
13251         unlinkmany $DIR/$tdir/f $nr
13252 }
13253 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13254
13255 test_134b() {
13256         remote_mds_nodsh && skip "remote MDS with nodsh"
13257         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13258                 skip "Need MDS version at least 2.7.54"
13259
13260         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13261         cancel_lru_locks mdc
13262
13263         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13264                         ldlm.lock_reclaim_threshold_mb)
13265         # disable reclaim temporarily
13266         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13267
13268         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13269         do_facet mds1 $LCTL set_param fail_loc=0x328
13270         do_facet mds1 $LCTL set_param fail_val=500
13271
13272         $LCTL set_param debug=+trace
13273
13274         local nr=600
13275         createmany -o $DIR/$tdir/f $nr &
13276         local create_pid=$!
13277
13278         echo "Sleep $TIMEOUT seconds ..."
13279         sleep $TIMEOUT
13280         if ! ps -p $create_pid  > /dev/null 2>&1; then
13281                 do_facet mds1 $LCTL set_param fail_loc=0
13282                 do_facet mds1 $LCTL set_param fail_val=0
13283                 do_facet mds1 $LCTL set_param \
13284                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13285                 error "createmany finished incorrectly!"
13286         fi
13287         do_facet mds1 $LCTL set_param fail_loc=0
13288         do_facet mds1 $LCTL set_param fail_val=0
13289         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13290         wait $create_pid || return 1
13291
13292         unlinkmany $DIR/$tdir/f $nr
13293 }
13294 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13295
13296 test_135() {
13297         remote_mds_nodsh && skip "remote MDS with nodsh"
13298         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13299                 skip "Need MDS version at least 2.13.50"
13300         local fname
13301
13302         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13303
13304 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13305         #set only one record at plain llog
13306         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13307
13308         #fill already existed plain llog each 64767
13309         #wrapping whole catalog
13310         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13311
13312         createmany -o $DIR/$tdir/$tfile_ 64700
13313         for (( i = 0; i < 64700; i = i + 2 ))
13314         do
13315                 rm $DIR/$tdir/$tfile_$i &
13316                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13317                 local pid=$!
13318                 wait $pid
13319         done
13320
13321         #waiting osp synchronization
13322         wait_delete_completed
13323 }
13324 run_test 135 "Race catalog processing"
13325
13326 test_136() {
13327         remote_mds_nodsh && skip "remote MDS with nodsh"
13328         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13329                 skip "Need MDS version at least 2.13.50"
13330         local fname
13331
13332         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13333         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13334         #set only one record at plain llog
13335 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13337
13338         #fill already existed 2 plain llogs each 64767
13339         #wrapping whole catalog
13340         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13341         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13342         wait_delete_completed
13343
13344         createmany -o $DIR/$tdir/$tfile_ 10
13345         sleep 25
13346
13347         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13348         for (( i = 0; i < 10; i = i + 3 ))
13349         do
13350                 rm $DIR/$tdir/$tfile_$i &
13351                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13352                 local pid=$!
13353                 wait $pid
13354                 sleep 7
13355                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13356         done
13357
13358         #waiting osp synchronization
13359         wait_delete_completed
13360 }
13361 run_test 136 "Race catalog processing 2"
13362
13363 test_140() { #bug-17379
13364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13365
13366         test_mkdir $DIR/$tdir
13367         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13368         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13369
13370         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13371         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13372         local i=0
13373         while i=$((i + 1)); do
13374                 test_mkdir $i
13375                 cd $i || error "Changing to $i"
13376                 ln -s ../stat stat || error "Creating stat symlink"
13377                 # Read the symlink until ELOOP present,
13378                 # not LBUGing the system is considered success,
13379                 # we didn't overrun the stack.
13380                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13381                 if [ $ret -ne 0 ]; then
13382                         if [ $ret -eq 40 ]; then
13383                                 break  # -ELOOP
13384                         else
13385                                 error "Open stat symlink"
13386                                         return
13387                         fi
13388                 fi
13389         done
13390         i=$((i - 1))
13391         echo "The symlink depth = $i"
13392         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13393                 error "Invalid symlink depth"
13394
13395         # Test recursive symlink
13396         ln -s symlink_self symlink_self
13397         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13398         echo "open symlink_self returns $ret"
13399         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13400 }
13401 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13402
13403 test_150a() {
13404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13405
13406         local TF="$TMP/$tfile"
13407
13408         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13409         cp $TF $DIR/$tfile
13410         cancel_lru_locks $OSC
13411         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13412         remount_client $MOUNT
13413         df -P $MOUNT
13414         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13415
13416         $TRUNCATE $TF 6000
13417         $TRUNCATE $DIR/$tfile 6000
13418         cancel_lru_locks $OSC
13419         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13420
13421         echo "12345" >>$TF
13422         echo "12345" >>$DIR/$tfile
13423         cancel_lru_locks $OSC
13424         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13425
13426         echo "12345" >>$TF
13427         echo "12345" >>$DIR/$tfile
13428         cancel_lru_locks $OSC
13429         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13430
13431         rm -f $TF
13432         true
13433 }
13434 run_test 150a "truncate/append tests"
13435
13436 test_150b() {
13437         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13438         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13439                 skip "Need OST version at least 2.13.53"
13440         touch $DIR/$tfile
13441         check_fallocate $DIR/$tfile || error "fallocate failed"
13442 }
13443 run_test 150b "Verify fallocate (prealloc) functionality"
13444
13445 test_150c() {
13446         local bytes
13447         local want
13448
13449         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13450         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13451                 skip "Need OST version at least 2.13.53"
13452
13453         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13454         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13455         sync; sync_all_data
13456         cancel_lru_locks $OSC
13457         sleep 5
13458         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13459         want=$((OSTCOUNT * 1048576))
13460
13461         # Must allocate all requested space, not more than 5% extra
13462         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13463                 error "bytes $bytes is not $want"
13464
13465         rm -f $DIR/$tfile
13466         # verify fallocate on PFL file
13467         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13468                 error "Create $DIR/$tfile failed"
13469         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13470                         error "fallocate failed"
13471         sync; sync_all_data
13472         cancel_lru_locks $OSC
13473         sleep 5
13474         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13475         want=$((1024 * 1048576))
13476
13477         # Must allocate all requested space, not more than 5% extra
13478         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13479                 error "bytes $bytes is not $want"
13480 }
13481 run_test 150c "Verify fallocate Size and Blocks"
13482
13483 test_150d() {
13484         local bytes
13485         local want
13486
13487         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13488         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13489                 skip "Need OST version at least 2.13.53"
13490
13491         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13492         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13493         sync; sync_all_data
13494         cancel_lru_locks $OSC
13495         sleep 5
13496         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13497         want=$((OSTCOUNT * 1048576))
13498
13499         # Must allocate all requested space, not more than 5% extra
13500         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13501                 error "bytes $bytes is not $want"
13502 }
13503 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13504
13505 test_150e() {
13506         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13507         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13508                 skip "Need OST version at least 2.13.55"
13509
13510         echo "df before:"
13511         $LFS df
13512         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13513                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13514
13515         # Find OST with Minimum Size
13516         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13517                        sort -un | head -1)
13518
13519         # Get 90% of the available space
13520         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13521
13522         fallocate -l${space}k $DIR/$tfile ||
13523                 error "fallocate ${space}k $DIR/$tfile failed"
13524         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13525
13526         # get size immediately after fallocate. This should be correctly
13527         # updated
13528         local size=$(stat -c '%s' $DIR/$tfile)
13529         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13530
13531         # Sleep for a while for statfs to get updated. And not pull from cache.
13532         sleep 2
13533
13534         echo "df after fallocate:"
13535         $LFS df
13536
13537         (( size / 1024 == space )) || error "size $size != requested $space"
13538         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13539                 error "used $used < space $space"
13540
13541         rm $DIR/$tfile || error "rm failed"
13542         sync
13543         wait_delete_completed
13544
13545         echo "df after unlink:"
13546         $LFS df
13547 }
13548 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13549
13550 #LU-2902 roc_hit was not able to read all values from lproc
13551 function roc_hit_init() {
13552         local list=$(comma_list $(osts_nodes))
13553         local dir=$DIR/$tdir-check
13554         local file=$dir/$tfile
13555         local BEFORE
13556         local AFTER
13557         local idx
13558
13559         test_mkdir $dir
13560         #use setstripe to do a write to every ost
13561         for i in $(seq 0 $((OSTCOUNT-1))); do
13562                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13563                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13564                 idx=$(printf %04x $i)
13565                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13566                         awk '$1 == "cache_access" {sum += $7}
13567                                 END { printf("%0.0f", sum) }')
13568
13569                 cancel_lru_locks osc
13570                 cat $file >/dev/null
13571
13572                 AFTER=$(get_osd_param $list *OST*$idx stats |
13573                         awk '$1 == "cache_access" {sum += $7}
13574                                 END { printf("%0.0f", sum) }')
13575
13576                 echo BEFORE:$BEFORE AFTER:$AFTER
13577                 if ! let "AFTER - BEFORE == 4"; then
13578                         rm -rf $dir
13579                         error "roc_hit is not safe to use"
13580                 fi
13581                 rm $file
13582         done
13583
13584         rm -rf $dir
13585 }
13586
13587 function roc_hit() {
13588         local list=$(comma_list $(osts_nodes))
13589         echo $(get_osd_param $list '' stats |
13590                 awk '$1 == "cache_hit" {sum += $7}
13591                         END { printf("%0.0f", sum) }')
13592 }
13593
13594 function set_cache() {
13595         local on=1
13596
13597         if [ "$2" == "off" ]; then
13598                 on=0;
13599         fi
13600         local list=$(comma_list $(osts_nodes))
13601         set_osd_param $list '' $1_cache_enable $on
13602
13603         cancel_lru_locks osc
13604 }
13605
13606 test_151() {
13607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13608         remote_ost_nodsh && skip "remote OST with nodsh"
13609
13610         local CPAGES=3
13611         local list=$(comma_list $(osts_nodes))
13612
13613         # check whether obdfilter is cache capable at all
13614         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13615                 skip "not cache-capable obdfilter"
13616         fi
13617
13618         # check cache is enabled on all obdfilters
13619         if get_osd_param $list '' read_cache_enable | grep 0; then
13620                 skip "oss cache is disabled"
13621         fi
13622
13623         set_osd_param $list '' writethrough_cache_enable 1
13624
13625         # check write cache is enabled on all obdfilters
13626         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13627                 skip "oss write cache is NOT enabled"
13628         fi
13629
13630         roc_hit_init
13631
13632         #define OBD_FAIL_OBD_NO_LRU  0x609
13633         do_nodes $list $LCTL set_param fail_loc=0x609
13634
13635         # pages should be in the case right after write
13636         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13637                 error "dd failed"
13638
13639         local BEFORE=$(roc_hit)
13640         cancel_lru_locks osc
13641         cat $DIR/$tfile >/dev/null
13642         local AFTER=$(roc_hit)
13643
13644         do_nodes $list $LCTL set_param fail_loc=0
13645
13646         if ! let "AFTER - BEFORE == CPAGES"; then
13647                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13648         fi
13649
13650         cancel_lru_locks osc
13651         # invalidates OST cache
13652         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13653         set_osd_param $list '' read_cache_enable 0
13654         cat $DIR/$tfile >/dev/null
13655
13656         # now data shouldn't be found in the cache
13657         BEFORE=$(roc_hit)
13658         cancel_lru_locks osc
13659         cat $DIR/$tfile >/dev/null
13660         AFTER=$(roc_hit)
13661         if let "AFTER - BEFORE != 0"; then
13662                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13663         fi
13664
13665         set_osd_param $list '' read_cache_enable 1
13666         rm -f $DIR/$tfile
13667 }
13668 run_test 151 "test cache on oss and controls ==============================="
13669
13670 test_152() {
13671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13672
13673         local TF="$TMP/$tfile"
13674
13675         # simulate ENOMEM during write
13676 #define OBD_FAIL_OST_NOMEM      0x226
13677         lctl set_param fail_loc=0x80000226
13678         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13679         cp $TF $DIR/$tfile
13680         sync || error "sync failed"
13681         lctl set_param fail_loc=0
13682
13683         # discard client's cache
13684         cancel_lru_locks osc
13685
13686         # simulate ENOMEM during read
13687         lctl set_param fail_loc=0x80000226
13688         cmp $TF $DIR/$tfile || error "cmp failed"
13689         lctl set_param fail_loc=0
13690
13691         rm -f $TF
13692 }
13693 run_test 152 "test read/write with enomem ============================"
13694
13695 test_153() {
13696         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13697 }
13698 run_test 153 "test if fdatasync does not crash ======================="
13699
13700 dot_lustre_fid_permission_check() {
13701         local fid=$1
13702         local ffid=$MOUNT/.lustre/fid/$fid
13703         local test_dir=$2
13704
13705         echo "stat fid $fid"
13706         stat $ffid > /dev/null || error "stat $ffid failed."
13707         echo "touch fid $fid"
13708         touch $ffid || error "touch $ffid failed."
13709         echo "write to fid $fid"
13710         cat /etc/hosts > $ffid || error "write $ffid failed."
13711         echo "read fid $fid"
13712         diff /etc/hosts $ffid || error "read $ffid failed."
13713         echo "append write to fid $fid"
13714         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13715         echo "rename fid $fid"
13716         mv $ffid $test_dir/$tfile.1 &&
13717                 error "rename $ffid to $tfile.1 should fail."
13718         touch $test_dir/$tfile.1
13719         mv $test_dir/$tfile.1 $ffid &&
13720                 error "rename $tfile.1 to $ffid should fail."
13721         rm -f $test_dir/$tfile.1
13722         echo "truncate fid $fid"
13723         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13724         echo "link fid $fid"
13725         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13726         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13727                 echo "setfacl fid $fid"
13728                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13729                 echo "getfacl fid $fid"
13730                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13731         fi
13732         echo "unlink fid $fid"
13733         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13734         echo "mknod fid $fid"
13735         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13736
13737         fid=[0xf00000400:0x1:0x0]
13738         ffid=$MOUNT/.lustre/fid/$fid
13739
13740         echo "stat non-exist fid $fid"
13741         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13742         echo "write to non-exist fid $fid"
13743         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13744         echo "link new fid $fid"
13745         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13746
13747         mkdir -p $test_dir/$tdir
13748         touch $test_dir/$tdir/$tfile
13749         fid=$($LFS path2fid $test_dir/$tdir)
13750         rc=$?
13751         [ $rc -ne 0 ] &&
13752                 error "error: could not get fid for $test_dir/$dir/$tfile."
13753
13754         ffid=$MOUNT/.lustre/fid/$fid
13755
13756         echo "ls $fid"
13757         ls $ffid > /dev/null || error "ls $ffid failed."
13758         echo "touch $fid/$tfile.1"
13759         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13760
13761         echo "touch $MOUNT/.lustre/fid/$tfile"
13762         touch $MOUNT/.lustre/fid/$tfile && \
13763                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13764
13765         echo "setxattr to $MOUNT/.lustre/fid"
13766         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13767
13768         echo "listxattr for $MOUNT/.lustre/fid"
13769         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13770
13771         echo "delxattr from $MOUNT/.lustre/fid"
13772         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13773
13774         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13775         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13776                 error "touch invalid fid should fail."
13777
13778         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13779         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13780                 error "touch non-normal fid should fail."
13781
13782         echo "rename $tdir to $MOUNT/.lustre/fid"
13783         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13784                 error "rename to $MOUNT/.lustre/fid should fail."
13785
13786         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13787         then            # LU-3547
13788                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13789                 local new_obf_mode=777
13790
13791                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13792                 chmod $new_obf_mode $DIR/.lustre/fid ||
13793                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13794
13795                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13796                 [ $obf_mode -eq $new_obf_mode ] ||
13797                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13798
13799                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13800                 chmod $old_obf_mode $DIR/.lustre/fid ||
13801                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13802         fi
13803
13804         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13805         fid=$($LFS path2fid $test_dir/$tfile-2)
13806
13807         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13808         then # LU-5424
13809                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13810                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13811                         error "create lov data thru .lustre failed"
13812         fi
13813         echo "cp /etc/passwd $test_dir/$tfile-2"
13814         cp /etc/passwd $test_dir/$tfile-2 ||
13815                 error "copy to $test_dir/$tfile-2 failed."
13816         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13817         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13818                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13819
13820         rm -rf $test_dir/tfile.lnk
13821         rm -rf $test_dir/$tfile-2
13822 }
13823
13824 test_154A() {
13825         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13826                 skip "Need MDS version at least 2.4.1"
13827
13828         local tf=$DIR/$tfile
13829         touch $tf
13830
13831         local fid=$($LFS path2fid $tf)
13832         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13833
13834         # check that we get the same pathname back
13835         local rootpath
13836         local found
13837         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13838                 echo "$rootpath $fid"
13839                 found=$($LFS fid2path $rootpath "$fid")
13840                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13841                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13842         done
13843
13844         # check wrong root path format
13845         rootpath=$MOUNT"_wrong"
13846         found=$($LFS fid2path $rootpath "$fid")
13847         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13848 }
13849 run_test 154A "lfs path2fid and fid2path basic checks"
13850
13851 test_154B() {
13852         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13853                 skip "Need MDS version at least 2.4.1"
13854
13855         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13856         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13857         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13858         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13859
13860         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13861         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13862
13863         # check that we get the same pathname
13864         echo "PFID: $PFID, name: $name"
13865         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13866         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13867         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13868                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13869
13870         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13871 }
13872 run_test 154B "verify the ll_decode_linkea tool"
13873
13874 test_154a() {
13875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13876         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13877         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13878                 skip "Need MDS version at least 2.2.51"
13879         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13880
13881         cp /etc/hosts $DIR/$tfile
13882
13883         fid=$($LFS path2fid $DIR/$tfile)
13884         rc=$?
13885         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13886
13887         dot_lustre_fid_permission_check "$fid" $DIR ||
13888                 error "dot lustre permission check $fid failed"
13889
13890         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13891
13892         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13893
13894         touch $MOUNT/.lustre/file &&
13895                 error "creation is not allowed under .lustre"
13896
13897         mkdir $MOUNT/.lustre/dir &&
13898                 error "mkdir is not allowed under .lustre"
13899
13900         rm -rf $DIR/$tfile
13901 }
13902 run_test 154a "Open-by-FID"
13903
13904 test_154b() {
13905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13906         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13908         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13909                 skip "Need MDS version at least 2.2.51"
13910
13911         local remote_dir=$DIR/$tdir/remote_dir
13912         local MDTIDX=1
13913         local rc=0
13914
13915         mkdir -p $DIR/$tdir
13916         $LFS mkdir -i $MDTIDX $remote_dir ||
13917                 error "create remote directory failed"
13918
13919         cp /etc/hosts $remote_dir/$tfile
13920
13921         fid=$($LFS path2fid $remote_dir/$tfile)
13922         rc=$?
13923         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13924
13925         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13926                 error "dot lustre permission check $fid failed"
13927         rm -rf $DIR/$tdir
13928 }
13929 run_test 154b "Open-by-FID for remote directory"
13930
13931 test_154c() {
13932         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13933                 skip "Need MDS version at least 2.4.1"
13934
13935         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13936         local FID1=$($LFS path2fid $DIR/$tfile.1)
13937         local FID2=$($LFS path2fid $DIR/$tfile.2)
13938         local FID3=$($LFS path2fid $DIR/$tfile.3)
13939
13940         local N=1
13941         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13942                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13943                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13944                 local want=FID$N
13945                 [ "$FID" = "${!want}" ] ||
13946                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13947                 N=$((N + 1))
13948         done
13949
13950         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13951         do
13952                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13953                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13954                 N=$((N + 1))
13955         done
13956 }
13957 run_test 154c "lfs path2fid and fid2path multiple arguments"
13958
13959 test_154d() {
13960         remote_mds_nodsh && skip "remote MDS with nodsh"
13961         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13962                 skip "Need MDS version at least 2.5.53"
13963
13964         if remote_mds; then
13965                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13966         else
13967                 nid="0@lo"
13968         fi
13969         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13970         local fd
13971         local cmd
13972
13973         rm -f $DIR/$tfile
13974         touch $DIR/$tfile
13975
13976         local fid=$($LFS path2fid $DIR/$tfile)
13977         # Open the file
13978         fd=$(free_fd)
13979         cmd="exec $fd<$DIR/$tfile"
13980         eval $cmd
13981         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13982         echo "$fid_list" | grep "$fid"
13983         rc=$?
13984
13985         cmd="exec $fd>/dev/null"
13986         eval $cmd
13987         if [ $rc -ne 0 ]; then
13988                 error "FID $fid not found in open files list $fid_list"
13989         fi
13990 }
13991 run_test 154d "Verify open file fid"
13992
13993 test_154e()
13994 {
13995         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13996                 skip "Need MDS version at least 2.6.50"
13997
13998         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13999                 error ".lustre returned by readdir"
14000         fi
14001 }
14002 run_test 154e ".lustre is not returned by readdir"
14003
14004 test_154f() {
14005         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14006
14007         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14008         test_mkdir -p -c1 $DIR/$tdir/d
14009         # test dirs inherit from its stripe
14010         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14011         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14012         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14013         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14014         touch $DIR/f
14015
14016         # get fid of parents
14017         local FID0=$($LFS path2fid $DIR/$tdir/d)
14018         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14019         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14020         local FID3=$($LFS path2fid $DIR)
14021
14022         # check that path2fid --parents returns expected <parent_fid>/name
14023         # 1) test for a directory (single parent)
14024         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14025         [ "$parent" == "$FID0/foo1" ] ||
14026                 error "expected parent: $FID0/foo1, got: $parent"
14027
14028         # 2) test for a file with nlink > 1 (multiple parents)
14029         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14030         echo "$parent" | grep -F "$FID1/$tfile" ||
14031                 error "$FID1/$tfile not returned in parent list"
14032         echo "$parent" | grep -F "$FID2/link" ||
14033                 error "$FID2/link not returned in parent list"
14034
14035         # 3) get parent by fid
14036         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14037         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14038         echo "$parent" | grep -F "$FID1/$tfile" ||
14039                 error "$FID1/$tfile not returned in parent list (by fid)"
14040         echo "$parent" | grep -F "$FID2/link" ||
14041                 error "$FID2/link not returned in parent list (by fid)"
14042
14043         # 4) test for entry in root directory
14044         parent=$($LFS path2fid --parents $DIR/f)
14045         echo "$parent" | grep -F "$FID3/f" ||
14046                 error "$FID3/f not returned in parent list"
14047
14048         # 5) test it on root directory
14049         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14050                 error "$MOUNT should not have parents"
14051
14052         # enable xattr caching and check that linkea is correctly updated
14053         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14054         save_lustre_params client "llite.*.xattr_cache" > $save
14055         lctl set_param llite.*.xattr_cache 1
14056
14057         # 6.1) linkea update on rename
14058         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14059
14060         # get parents by fid
14061         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14062         # foo1 should no longer be returned in parent list
14063         echo "$parent" | grep -F "$FID1" &&
14064                 error "$FID1 should no longer be in parent list"
14065         # the new path should appear
14066         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14067                 error "$FID2/$tfile.moved is not in parent list"
14068
14069         # 6.2) linkea update on unlink
14070         rm -f $DIR/$tdir/d/foo2/link
14071         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14072         # foo2/link should no longer be returned in parent list
14073         echo "$parent" | grep -F "$FID2/link" &&
14074                 error "$FID2/link should no longer be in parent list"
14075         true
14076
14077         rm -f $DIR/f
14078         restore_lustre_params < $save
14079         rm -f $save
14080 }
14081 run_test 154f "get parent fids by reading link ea"
14082
14083 test_154g()
14084 {
14085         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14086         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14087            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14088                 skip "Need MDS version at least 2.6.92"
14089
14090         mkdir -p $DIR/$tdir
14091         llapi_fid_test -d $DIR/$tdir
14092 }
14093 run_test 154g "various llapi FID tests"
14094
14095 test_155_small_load() {
14096     local temp=$TMP/$tfile
14097     local file=$DIR/$tfile
14098
14099     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14100         error "dd of=$temp bs=6096 count=1 failed"
14101     cp $temp $file
14102     cancel_lru_locks $OSC
14103     cmp $temp $file || error "$temp $file differ"
14104
14105     $TRUNCATE $temp 6000
14106     $TRUNCATE $file 6000
14107     cmp $temp $file || error "$temp $file differ (truncate1)"
14108
14109     echo "12345" >>$temp
14110     echo "12345" >>$file
14111     cmp $temp $file || error "$temp $file differ (append1)"
14112
14113     echo "12345" >>$temp
14114     echo "12345" >>$file
14115     cmp $temp $file || error "$temp $file differ (append2)"
14116
14117     rm -f $temp $file
14118     true
14119 }
14120
14121 test_155_big_load() {
14122         remote_ost_nodsh && skip "remote OST with nodsh"
14123
14124         local temp=$TMP/$tfile
14125         local file=$DIR/$tfile
14126
14127         free_min_max
14128         local cache_size=$(do_facet ost$((MAXI+1)) \
14129                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14130         local large_file_size=$((cache_size * 2))
14131
14132         echo "OSS cache size: $cache_size KB"
14133         echo "Large file size: $large_file_size KB"
14134
14135         [ $MAXV -le $large_file_size ] &&
14136                 skip_env "max available OST size needs > $large_file_size KB"
14137
14138         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14139
14140         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14141                 error "dd of=$temp bs=$large_file_size count=1k failed"
14142         cp $temp $file
14143         ls -lh $temp $file
14144         cancel_lru_locks osc
14145         cmp $temp $file || error "$temp $file differ"
14146
14147         rm -f $temp $file
14148         true
14149 }
14150
14151 save_writethrough() {
14152         local facets=$(get_facets OST)
14153
14154         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14155 }
14156
14157 test_155a() {
14158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14159
14160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14161
14162         save_writethrough $p
14163
14164         set_cache read on
14165         set_cache writethrough on
14166         test_155_small_load
14167         restore_lustre_params < $p
14168         rm -f $p
14169 }
14170 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14171
14172 test_155b() {
14173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14174
14175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14176
14177         save_writethrough $p
14178
14179         set_cache read on
14180         set_cache writethrough off
14181         test_155_small_load
14182         restore_lustre_params < $p
14183         rm -f $p
14184 }
14185 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14186
14187 test_155c() {
14188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14189
14190         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14191
14192         save_writethrough $p
14193
14194         set_cache read off
14195         set_cache writethrough on
14196         test_155_small_load
14197         restore_lustre_params < $p
14198         rm -f $p
14199 }
14200 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14201
14202 test_155d() {
14203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14204
14205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14206
14207         save_writethrough $p
14208
14209         set_cache read off
14210         set_cache writethrough off
14211         test_155_small_load
14212         restore_lustre_params < $p
14213         rm -f $p
14214 }
14215 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14216
14217 test_155e() {
14218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14219
14220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14221
14222         save_writethrough $p
14223
14224         set_cache read on
14225         set_cache writethrough on
14226         test_155_big_load
14227         restore_lustre_params < $p
14228         rm -f $p
14229 }
14230 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14231
14232 test_155f() {
14233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14234
14235         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14236
14237         save_writethrough $p
14238
14239         set_cache read on
14240         set_cache writethrough off
14241         test_155_big_load
14242         restore_lustre_params < $p
14243         rm -f $p
14244 }
14245 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14246
14247 test_155g() {
14248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14249
14250         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14251
14252         save_writethrough $p
14253
14254         set_cache read off
14255         set_cache writethrough on
14256         test_155_big_load
14257         restore_lustre_params < $p
14258         rm -f $p
14259 }
14260 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14261
14262 test_155h() {
14263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14264
14265         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14266
14267         save_writethrough $p
14268
14269         set_cache read off
14270         set_cache writethrough off
14271         test_155_big_load
14272         restore_lustre_params < $p
14273         rm -f $p
14274 }
14275 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14276
14277 test_156() {
14278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14279         remote_ost_nodsh && skip "remote OST with nodsh"
14280         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14281                 skip "stats not implemented on old servers"
14282         [ "$ost1_FSTYPE" = "zfs" ] &&
14283                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14284
14285         local CPAGES=3
14286         local BEFORE
14287         local AFTER
14288         local file="$DIR/$tfile"
14289         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14290
14291         save_writethrough $p
14292         roc_hit_init
14293
14294         log "Turn on read and write cache"
14295         set_cache read on
14296         set_cache writethrough on
14297
14298         log "Write data and read it back."
14299         log "Read should be satisfied from the cache."
14300         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14301         BEFORE=$(roc_hit)
14302         cancel_lru_locks osc
14303         cat $file >/dev/null
14304         AFTER=$(roc_hit)
14305         if ! let "AFTER - BEFORE == CPAGES"; then
14306                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14307         else
14308                 log "cache hits: before: $BEFORE, after: $AFTER"
14309         fi
14310
14311         log "Read again; it should be satisfied from the cache."
14312         BEFORE=$AFTER
14313         cancel_lru_locks osc
14314         cat $file >/dev/null
14315         AFTER=$(roc_hit)
14316         if ! let "AFTER - BEFORE == CPAGES"; then
14317                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14318         else
14319                 log "cache hits:: before: $BEFORE, after: $AFTER"
14320         fi
14321
14322         log "Turn off the read cache and turn on the write cache"
14323         set_cache read off
14324         set_cache writethrough on
14325
14326         log "Read again; it should be satisfied from the cache."
14327         BEFORE=$(roc_hit)
14328         cancel_lru_locks osc
14329         cat $file >/dev/null
14330         AFTER=$(roc_hit)
14331         if ! let "AFTER - BEFORE == CPAGES"; then
14332                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14333         else
14334                 log "cache hits:: before: $BEFORE, after: $AFTER"
14335         fi
14336
14337         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14338                 # > 2.12.56 uses pagecache if cached
14339                 log "Read again; it should not be satisfied from the cache."
14340                 BEFORE=$AFTER
14341                 cancel_lru_locks osc
14342                 cat $file >/dev/null
14343                 AFTER=$(roc_hit)
14344                 if ! let "AFTER - BEFORE == 0"; then
14345                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14346                 else
14347                         log "cache hits:: before: $BEFORE, after: $AFTER"
14348                 fi
14349         fi
14350
14351         log "Write data and read it back."
14352         log "Read should be satisfied from the cache."
14353         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14354         BEFORE=$(roc_hit)
14355         cancel_lru_locks osc
14356         cat $file >/dev/null
14357         AFTER=$(roc_hit)
14358         if ! let "AFTER - BEFORE == CPAGES"; then
14359                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14360         else
14361                 log "cache hits:: before: $BEFORE, after: $AFTER"
14362         fi
14363
14364         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14365                 # > 2.12.56 uses pagecache if cached
14366                 log "Read again; it should not be satisfied from the cache."
14367                 BEFORE=$AFTER
14368                 cancel_lru_locks osc
14369                 cat $file >/dev/null
14370                 AFTER=$(roc_hit)
14371                 if ! let "AFTER - BEFORE == 0"; then
14372                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14373                 else
14374                         log "cache hits:: before: $BEFORE, after: $AFTER"
14375                 fi
14376         fi
14377
14378         log "Turn off read and write cache"
14379         set_cache read off
14380         set_cache writethrough off
14381
14382         log "Write data and read it back"
14383         log "It should not be satisfied from the cache."
14384         rm -f $file
14385         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14386         cancel_lru_locks osc
14387         BEFORE=$(roc_hit)
14388         cat $file >/dev/null
14389         AFTER=$(roc_hit)
14390         if ! let "AFTER - BEFORE == 0"; then
14391                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14392         else
14393                 log "cache hits:: before: $BEFORE, after: $AFTER"
14394         fi
14395
14396         log "Turn on the read cache and turn off the write cache"
14397         set_cache read on
14398         set_cache writethrough off
14399
14400         log "Write data and read it back"
14401         log "It should not be satisfied from the cache."
14402         rm -f $file
14403         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14404         BEFORE=$(roc_hit)
14405         cancel_lru_locks osc
14406         cat $file >/dev/null
14407         AFTER=$(roc_hit)
14408         if ! let "AFTER - BEFORE == 0"; then
14409                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14410         else
14411                 log "cache hits:: before: $BEFORE, after: $AFTER"
14412         fi
14413
14414         log "Read again; it should be satisfied from the cache."
14415         BEFORE=$(roc_hit)
14416         cancel_lru_locks osc
14417         cat $file >/dev/null
14418         AFTER=$(roc_hit)
14419         if ! let "AFTER - BEFORE == CPAGES"; then
14420                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14421         else
14422                 log "cache hits:: before: $BEFORE, after: $AFTER"
14423         fi
14424
14425         restore_lustre_params < $p
14426         rm -f $p $file
14427 }
14428 run_test 156 "Verification of tunables"
14429
14430 test_160a() {
14431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14432         remote_mds_nodsh && skip "remote MDS with nodsh"
14433         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14434                 skip "Need MDS version at least 2.2.0"
14435
14436         changelog_register || error "changelog_register failed"
14437         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14438         changelog_users $SINGLEMDS | grep -q $cl_user ||
14439                 error "User $cl_user not found in changelog_users"
14440
14441         # change something
14442         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14443         changelog_clear 0 || error "changelog_clear failed"
14444         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14445         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14446         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14447         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14448         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14449         rm $DIR/$tdir/pics/desktop.jpg
14450
14451         changelog_dump | tail -10
14452
14453         echo "verifying changelog mask"
14454         changelog_chmask "-MKDIR"
14455         changelog_chmask "-CLOSE"
14456
14457         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14458         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14459
14460         changelog_chmask "+MKDIR"
14461         changelog_chmask "+CLOSE"
14462
14463         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14464         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14465
14466         changelog_dump | tail -10
14467         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14468         CLOSES=$(changelog_dump | grep -c "CLOSE")
14469         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14470         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14471
14472         # verify contents
14473         echo "verifying target fid"
14474         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14475         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14476         [ "$fidc" == "$fidf" ] ||
14477                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14478         echo "verifying parent fid"
14479         # The FID returned from the Changelog may be the directory shard on
14480         # a different MDT, and not the FID returned by path2fid on the parent.
14481         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14482         # since this is what will matter when recreating this file in the tree.
14483         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14484         local pathp=$($LFS fid2path $MOUNT "$fidp")
14485         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14486                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14487
14488         echo "getting records for $cl_user"
14489         changelog_users $SINGLEMDS
14490         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14491         local nclr=3
14492         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14493                 error "changelog_clear failed"
14494         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14495         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14496         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14497                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14498
14499         local min0_rec=$(changelog_users $SINGLEMDS |
14500                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14501         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14502                           awk '{ print $1; exit; }')
14503
14504         changelog_dump | tail -n 5
14505         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14506         [ $first_rec == $((min0_rec + 1)) ] ||
14507                 error "first index should be $min0_rec + 1 not $first_rec"
14508
14509         # LU-3446 changelog index reset on MDT restart
14510         local cur_rec1=$(changelog_users $SINGLEMDS |
14511                          awk '/^current.index:/ { print $NF }')
14512         changelog_clear 0 ||
14513                 error "clear all changelog records for $cl_user failed"
14514         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14515         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14516                 error "Fail to start $SINGLEMDS"
14517         local cur_rec2=$(changelog_users $SINGLEMDS |
14518                          awk '/^current.index:/ { print $NF }')
14519         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14520         [ $cur_rec1 == $cur_rec2 ] ||
14521                 error "current index should be $cur_rec1 not $cur_rec2"
14522
14523         echo "verifying users from this test are deregistered"
14524         changelog_deregister || error "changelog_deregister failed"
14525         changelog_users $SINGLEMDS | grep -q $cl_user &&
14526                 error "User '$cl_user' still in changelog_users"
14527
14528         # lctl get_param -n mdd.*.changelog_users
14529         # current index: 144
14530         # ID    index (idle seconds)
14531         # cl3   144 (2)
14532         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14533                 # this is the normal case where all users were deregistered
14534                 # make sure no new records are added when no users are present
14535                 local last_rec1=$(changelog_users $SINGLEMDS |
14536                                   awk '/^current.index:/ { print $NF }')
14537                 touch $DIR/$tdir/chloe
14538                 local last_rec2=$(changelog_users $SINGLEMDS |
14539                                   awk '/^current.index:/ { print $NF }')
14540                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14541                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14542         else
14543                 # any changelog users must be leftovers from a previous test
14544                 changelog_users $SINGLEMDS
14545                 echo "other changelog users; can't verify off"
14546         fi
14547 }
14548 run_test 160a "changelog sanity"
14549
14550 test_160b() { # LU-3587
14551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14552         remote_mds_nodsh && skip "remote MDS with nodsh"
14553         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14554                 skip "Need MDS version at least 2.2.0"
14555
14556         changelog_register || error "changelog_register failed"
14557         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14558         changelog_users $SINGLEMDS | grep -q $cl_user ||
14559                 error "User '$cl_user' not found in changelog_users"
14560
14561         local longname1=$(str_repeat a 255)
14562         local longname2=$(str_repeat b 255)
14563
14564         cd $DIR
14565         echo "creating very long named file"
14566         touch $longname1 || error "create of '$longname1' failed"
14567         echo "renaming very long named file"
14568         mv $longname1 $longname2
14569
14570         changelog_dump | grep RENME | tail -n 5
14571         rm -f $longname2
14572 }
14573 run_test 160b "Verify that very long rename doesn't crash in changelog"
14574
14575 test_160c() {
14576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14577         remote_mds_nodsh && skip "remote MDS with nodsh"
14578
14579         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14580                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14581                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14582                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14583
14584         local rc=0
14585
14586         # Registration step
14587         changelog_register || error "changelog_register failed"
14588
14589         rm -rf $DIR/$tdir
14590         mkdir -p $DIR/$tdir
14591         $MCREATE $DIR/$tdir/foo_160c
14592         changelog_chmask "-TRUNC"
14593         $TRUNCATE $DIR/$tdir/foo_160c 200
14594         changelog_chmask "+TRUNC"
14595         $TRUNCATE $DIR/$tdir/foo_160c 199
14596         changelog_dump | tail -n 5
14597         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14598         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14599 }
14600 run_test 160c "verify that changelog log catch the truncate event"
14601
14602 test_160d() {
14603         remote_mds_nodsh && skip "remote MDS with nodsh"
14604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14606         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14607                 skip "Need MDS version at least 2.7.60"
14608
14609         # Registration step
14610         changelog_register || error "changelog_register failed"
14611
14612         mkdir -p $DIR/$tdir/migrate_dir
14613         changelog_clear 0 || error "changelog_clear failed"
14614
14615         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14616         changelog_dump | tail -n 5
14617         local migrates=$(changelog_dump | grep -c "MIGRT")
14618         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14619 }
14620 run_test 160d "verify that changelog log catch the migrate event"
14621
14622 test_160e() {
14623         remote_mds_nodsh && skip "remote MDS with nodsh"
14624
14625         # Create a user
14626         changelog_register || error "changelog_register failed"
14627
14628         # Delete a future user (expect fail)
14629         local MDT0=$(facet_svc $SINGLEMDS)
14630         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14631         local rc=$?
14632
14633         if [ $rc -eq 0 ]; then
14634                 error "Deleted non-existant user cl77"
14635         elif [ $rc -ne 2 ]; then
14636                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14637         fi
14638
14639         # Clear to a bad index (1 billion should be safe)
14640         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14641         rc=$?
14642
14643         if [ $rc -eq 0 ]; then
14644                 error "Successfully cleared to invalid CL index"
14645         elif [ $rc -ne 22 ]; then
14646                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14647         fi
14648 }
14649 run_test 160e "changelog negative testing (should return errors)"
14650
14651 test_160f() {
14652         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14653         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14654                 skip "Need MDS version at least 2.10.56"
14655
14656         local mdts=$(comma_list $(mdts_nodes))
14657
14658         # Create a user
14659         changelog_register || error "first changelog_register failed"
14660         changelog_register || error "second changelog_register failed"
14661         local cl_users
14662         declare -A cl_user1
14663         declare -A cl_user2
14664         local user_rec1
14665         local user_rec2
14666         local i
14667
14668         # generate some changelog records to accumulate on each MDT
14669         # use fnv1a because created files should be evenly distributed
14670         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14671                 error "test_mkdir $tdir failed"
14672         log "$(date +%s): creating first files"
14673         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14674                 error "create $DIR/$tdir/$tfile failed"
14675
14676         # check changelogs have been generated
14677         local start=$SECONDS
14678         local idle_time=$((MDSCOUNT * 5 + 5))
14679         local nbcl=$(changelog_dump | wc -l)
14680         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14681
14682         for param in "changelog_max_idle_time=$idle_time" \
14683                      "changelog_gc=1" \
14684                      "changelog_min_gc_interval=2" \
14685                      "changelog_min_free_cat_entries=3"; do
14686                 local MDT0=$(facet_svc $SINGLEMDS)
14687                 local var="${param%=*}"
14688                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14689
14690                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14691                 do_nodes $mdts $LCTL set_param mdd.*.$param
14692         done
14693
14694         # force cl_user2 to be idle (1st part), but also cancel the
14695         # cl_user1 records so that it is not evicted later in the test.
14696         local sleep1=$((idle_time / 2))
14697         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14698         sleep $sleep1
14699
14700         # simulate changelog catalog almost full
14701         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14702         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14703
14704         for i in $(seq $MDSCOUNT); do
14705                 cl_users=(${CL_USERS[mds$i]})
14706                 cl_user1[mds$i]="${cl_users[0]}"
14707                 cl_user2[mds$i]="${cl_users[1]}"
14708
14709                 [ -n "${cl_user1[mds$i]}" ] ||
14710                         error "mds$i: no user registered"
14711                 [ -n "${cl_user2[mds$i]}" ] ||
14712                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14713
14714                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14715                 [ -n "$user_rec1" ] ||
14716                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14717                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14718                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14719                 [ -n "$user_rec2" ] ||
14720                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14721                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14722                      "$user_rec1 + 2 == $user_rec2"
14723                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14724                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14725                               "$user_rec1 + 2, but is $user_rec2"
14726                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14727                 [ -n "$user_rec2" ] ||
14728                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14729                 [ $user_rec1 == $user_rec2 ] ||
14730                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14731                               "$user_rec1, but is $user_rec2"
14732         done
14733
14734         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14735         local sleep2=$((idle_time - (SECONDS - start) + 1))
14736         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14737         sleep $sleep2
14738
14739         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14740         # cl_user1 should be OK because it recently processed records.
14741         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14742         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14743                 error "create $DIR/$tdir/${tfile}b failed"
14744
14745         # ensure gc thread is done
14746         for i in $(mdts_nodes); do
14747                 wait_update $i \
14748                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14749                         error "$i: GC-thread not done"
14750         done
14751
14752         local first_rec
14753         for i in $(seq $MDSCOUNT); do
14754                 # check cl_user1 still registered
14755                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14756                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14757                 # check cl_user2 unregistered
14758                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14759                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14760
14761                 # check changelogs are present and starting at $user_rec1 + 1
14762                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14763                 [ -n "$user_rec1" ] ||
14764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14765                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14766                             awk '{ print $1; exit; }')
14767
14768                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14769                 [ $((user_rec1 + 1)) == $first_rec ] ||
14770                         error "mds$i: first index should be $user_rec1 + 1, " \
14771                               "but is $first_rec"
14772         done
14773 }
14774 run_test 160f "changelog garbage collect (timestamped users)"
14775
14776 test_160g() {
14777         remote_mds_nodsh && skip "remote MDS with nodsh"
14778         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14779                 skip "Need MDS version at least 2.10.56"
14780
14781         local mdts=$(comma_list $(mdts_nodes))
14782
14783         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14784         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14785
14786         # Create a user
14787         changelog_register || error "first changelog_register failed"
14788         changelog_register || error "second changelog_register failed"
14789         local cl_users
14790         declare -A cl_user1
14791         declare -A cl_user2
14792         local user_rec1
14793         local user_rec2
14794         local i
14795
14796         # generate some changelog records to accumulate on each MDT
14797         # use fnv1a because created files should be evenly distributed
14798         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14799                 error "mkdir $tdir failed"
14800         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14801                 error "create $DIR/$tdir/$tfile failed"
14802
14803         # check changelogs have been generated
14804         local nbcl=$(changelog_dump | wc -l)
14805         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14806
14807         # reduce the max_idle_indexes value to make sure we exceed it
14808         max_ndx=$((nbcl / 2 - 1))
14809
14810         for param in "changelog_max_idle_indexes=$max_ndx" \
14811                      "changelog_gc=1" \
14812                      "changelog_min_gc_interval=2" \
14813                      "changelog_min_free_cat_entries=3"; do
14814                 local MDT0=$(facet_svc $SINGLEMDS)
14815                 local var="${param%=*}"
14816                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14817
14818                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14819                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14820                         error "unable to set mdd.*.$param"
14821         done
14822
14823         # simulate changelog catalog almost full
14824         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14825         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14826
14827         for i in $(seq $MDSCOUNT); do
14828                 cl_users=(${CL_USERS[mds$i]})
14829                 cl_user1[mds$i]="${cl_users[0]}"
14830                 cl_user2[mds$i]="${cl_users[1]}"
14831
14832                 [ -n "${cl_user1[mds$i]}" ] ||
14833                         error "mds$i: no user registered"
14834                 [ -n "${cl_user2[mds$i]}" ] ||
14835                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14836
14837                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14838                 [ -n "$user_rec1" ] ||
14839                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14840                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14841                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14842                 [ -n "$user_rec2" ] ||
14843                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14844                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14845                      "$user_rec1 + 2 == $user_rec2"
14846                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14847                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14848                               "$user_rec1 + 2, but is $user_rec2"
14849                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14850                 [ -n "$user_rec2" ] ||
14851                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14852                 [ $user_rec1 == $user_rec2 ] ||
14853                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14854                               "$user_rec1, but is $user_rec2"
14855         done
14856
14857         # ensure we are past the previous changelog_min_gc_interval set above
14858         sleep 2
14859
14860         # generate one more changelog to trigger fail_loc
14861         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14862                 error "create $DIR/$tdir/${tfile}bis failed"
14863
14864         # ensure gc thread is done
14865         for i in $(mdts_nodes); do
14866                 wait_update $i \
14867                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14868                         error "$i: GC-thread not done"
14869         done
14870
14871         local first_rec
14872         for i in $(seq $MDSCOUNT); do
14873                 # check cl_user1 still registered
14874                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14875                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14876                 # check cl_user2 unregistered
14877                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14878                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14879
14880                 # check changelogs are present and starting at $user_rec1 + 1
14881                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14882                 [ -n "$user_rec1" ] ||
14883                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14884                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14885                             awk '{ print $1; exit; }')
14886
14887                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14888                 [ $((user_rec1 + 1)) == $first_rec ] ||
14889                         error "mds$i: first index should be $user_rec1 + 1, " \
14890                               "but is $first_rec"
14891         done
14892 }
14893 run_test 160g "changelog garbage collect (old users)"
14894
14895 test_160h() {
14896         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14897         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14898                 skip "Need MDS version at least 2.10.56"
14899
14900         local mdts=$(comma_list $(mdts_nodes))
14901
14902         # Create a user
14903         changelog_register || error "first changelog_register failed"
14904         changelog_register || error "second changelog_register failed"
14905         local cl_users
14906         declare -A cl_user1
14907         declare -A cl_user2
14908         local user_rec1
14909         local user_rec2
14910         local i
14911
14912         # generate some changelog records to accumulate on each MDT
14913         # use fnv1a because created files should be evenly distributed
14914         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14915                 error "test_mkdir $tdir failed"
14916         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14917                 error "create $DIR/$tdir/$tfile failed"
14918
14919         # check changelogs have been generated
14920         local nbcl=$(changelog_dump | wc -l)
14921         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14922
14923         for param in "changelog_max_idle_time=10" \
14924                      "changelog_gc=1" \
14925                      "changelog_min_gc_interval=2"; do
14926                 local MDT0=$(facet_svc $SINGLEMDS)
14927                 local var="${param%=*}"
14928                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14929
14930                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14931                 do_nodes $mdts $LCTL set_param mdd.*.$param
14932         done
14933
14934         # force cl_user2 to be idle (1st part)
14935         sleep 9
14936
14937         for i in $(seq $MDSCOUNT); do
14938                 cl_users=(${CL_USERS[mds$i]})
14939                 cl_user1[mds$i]="${cl_users[0]}"
14940                 cl_user2[mds$i]="${cl_users[1]}"
14941
14942                 [ -n "${cl_user1[mds$i]}" ] ||
14943                         error "mds$i: no user registered"
14944                 [ -n "${cl_user2[mds$i]}" ] ||
14945                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14946
14947                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14948                 [ -n "$user_rec1" ] ||
14949                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14950                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14951                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14952                 [ -n "$user_rec2" ] ||
14953                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14954                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14955                      "$user_rec1 + 2 == $user_rec2"
14956                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14957                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14958                               "$user_rec1 + 2, but is $user_rec2"
14959                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14960                 [ -n "$user_rec2" ] ||
14961                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14962                 [ $user_rec1 == $user_rec2 ] ||
14963                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14964                               "$user_rec1, but is $user_rec2"
14965         done
14966
14967         # force cl_user2 to be idle (2nd part) and to reach
14968         # changelog_max_idle_time
14969         sleep 2
14970
14971         # force each GC-thread start and block then
14972         # one per MDT/MDD, set fail_val accordingly
14973         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14974         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14975
14976         # generate more changelogs to trigger fail_loc
14977         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14978                 error "create $DIR/$tdir/${tfile}bis failed"
14979
14980         # stop MDT to stop GC-thread, should be done in back-ground as it will
14981         # block waiting for the thread to be released and exit
14982         declare -A stop_pids
14983         for i in $(seq $MDSCOUNT); do
14984                 stop mds$i &
14985                 stop_pids[mds$i]=$!
14986         done
14987
14988         for i in $(mdts_nodes); do
14989                 local facet
14990                 local nb=0
14991                 local facets=$(facets_up_on_host $i)
14992
14993                 for facet in ${facets//,/ }; do
14994                         if [[ $facet == mds* ]]; then
14995                                 nb=$((nb + 1))
14996                         fi
14997                 done
14998                 # ensure each MDS's gc threads are still present and all in "R"
14999                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15000                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15001                         error "$i: expected $nb GC-thread"
15002                 wait_update $i \
15003                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15004                         "R" 20 ||
15005                         error "$i: GC-thread not found in R-state"
15006                 # check umounts of each MDT on MDS have reached kthread_stop()
15007                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15008                         error "$i: expected $nb umount"
15009                 wait_update $i \
15010                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15011                         error "$i: umount not found in D-state"
15012         done
15013
15014         # release all GC-threads
15015         do_nodes $mdts $LCTL set_param fail_loc=0
15016
15017         # wait for MDT stop to complete
15018         for i in $(seq $MDSCOUNT); do
15019                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15020         done
15021
15022         # XXX
15023         # may try to check if any orphan changelog records are present
15024         # via ldiskfs/zfs and llog_reader...
15025
15026         # re-start/mount MDTs
15027         for i in $(seq $MDSCOUNT); do
15028                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15029                         error "Fail to start mds$i"
15030         done
15031
15032         local first_rec
15033         for i in $(seq $MDSCOUNT); do
15034                 # check cl_user1 still registered
15035                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15036                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15037                 # check cl_user2 unregistered
15038                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15039                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15040
15041                 # check changelogs are present and starting at $user_rec1 + 1
15042                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15043                 [ -n "$user_rec1" ] ||
15044                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15045                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15046                             awk '{ print $1; exit; }')
15047
15048                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15049                 [ $((user_rec1 + 1)) == $first_rec ] ||
15050                         error "mds$i: first index should be $user_rec1 + 1, " \
15051                               "but is $first_rec"
15052         done
15053 }
15054 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15055               "during mount"
15056
15057 test_160i() {
15058
15059         local mdts=$(comma_list $(mdts_nodes))
15060
15061         changelog_register || error "first changelog_register failed"
15062
15063         # generate some changelog records to accumulate on each MDT
15064         # use fnv1a because created files should be evenly distributed
15065         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15066                 error "mkdir $tdir failed"
15067         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15068                 error "create $DIR/$tdir/$tfile failed"
15069
15070         # check changelogs have been generated
15071         local nbcl=$(changelog_dump | wc -l)
15072         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15073
15074         # simulate race between register and unregister
15075         # XXX as fail_loc is set per-MDS, with DNE configs the race
15076         # simulation will only occur for one MDT per MDS and for the
15077         # others the normal race scenario will take place
15078         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15079         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15080         do_nodes $mdts $LCTL set_param fail_val=1
15081
15082         # unregister 1st user
15083         changelog_deregister &
15084         local pid1=$!
15085         # wait some time for deregister work to reach race rdv
15086         sleep 2
15087         # register 2nd user
15088         changelog_register || error "2nd user register failed"
15089
15090         wait $pid1 || error "1st user deregister failed"
15091
15092         local i
15093         local last_rec
15094         declare -A LAST_REC
15095         for i in $(seq $MDSCOUNT); do
15096                 if changelog_users mds$i | grep "^cl"; then
15097                         # make sure new records are added with one user present
15098                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15099                                           awk '/^current.index:/ { print $NF }')
15100                 else
15101                         error "mds$i has no user registered"
15102                 fi
15103         done
15104
15105         # generate more changelog records to accumulate on each MDT
15106         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15107                 error "create $DIR/$tdir/${tfile}bis failed"
15108
15109         for i in $(seq $MDSCOUNT); do
15110                 last_rec=$(changelog_users $SINGLEMDS |
15111                            awk '/^current.index:/ { print $NF }')
15112                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15113                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15114                         error "changelogs are off on mds$i"
15115         done
15116 }
15117 run_test 160i "changelog user register/unregister race"
15118
15119 test_160j() {
15120         remote_mds_nodsh && skip "remote MDS with nodsh"
15121         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15122                 skip "Need MDS version at least 2.12.56"
15123
15124         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15125         stack_trap "umount $MOUNT2" EXIT
15126
15127         changelog_register || error "first changelog_register failed"
15128         stack_trap "changelog_deregister" EXIT
15129
15130         # generate some changelog
15131         # use fnv1a because created files should be evenly distributed
15132         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15133                 error "mkdir $tdir failed"
15134         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15135                 error "create $DIR/$tdir/${tfile}bis failed"
15136
15137         # open the changelog device
15138         exec 3>/dev/changelog-$FSNAME-MDT0000
15139         stack_trap "exec 3>&-" EXIT
15140         exec 4</dev/changelog-$FSNAME-MDT0000
15141         stack_trap "exec 4<&-" EXIT
15142
15143         # umount the first lustre mount
15144         umount $MOUNT
15145         stack_trap "mount_client $MOUNT" EXIT
15146
15147         # read changelog
15148         cat <&4 >/dev/null || error "read changelog failed"
15149
15150         # clear changelog
15151         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15152         changelog_users $SINGLEMDS | grep -q $cl_user ||
15153                 error "User $cl_user not found in changelog_users"
15154
15155         printf 'clear:'$cl_user':0' >&3
15156 }
15157 run_test 160j "client can be umounted  while its chanangelog is being used"
15158
15159 test_160k() {
15160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15161         remote_mds_nodsh && skip "remote MDS with nodsh"
15162
15163         mkdir -p $DIR/$tdir/1/1
15164
15165         changelog_register || error "changelog_register failed"
15166         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15167
15168         changelog_users $SINGLEMDS | grep -q $cl_user ||
15169                 error "User '$cl_user' not found in changelog_users"
15170 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15171         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15172         rmdir $DIR/$tdir/1/1 & sleep 1
15173         mkdir $DIR/$tdir/2
15174         touch $DIR/$tdir/2/2
15175         rm -rf $DIR/$tdir/2
15176
15177         wait
15178         sleep 4
15179
15180         changelog_dump | grep rmdir || error "rmdir not recorded"
15181
15182         rm -rf $DIR/$tdir
15183         changelog_deregister
15184 }
15185 run_test 160k "Verify that changelog records are not lost"
15186
15187 # Verifies that a file passed as a parameter has recently had an operation
15188 # performed on it that has generated an MTIME changelog which contains the
15189 # correct parent FID. As files might reside on a different MDT from the
15190 # parent directory in DNE configurations, the FIDs are translated to paths
15191 # before being compared, which should be identical
15192 compare_mtime_changelog() {
15193         local file="${1}"
15194         local mdtidx
15195         local mtime
15196         local cl_fid
15197         local pdir
15198         local dir
15199
15200         mdtidx=$($LFS getstripe --mdt-index $file)
15201         mdtidx=$(printf "%04x" $mdtidx)
15202
15203         # Obtain the parent FID from the MTIME changelog
15204         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15205         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15206
15207         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15208         [ -z "$cl_fid" ] && error "parent FID not present"
15209
15210         # Verify that the path for the parent FID is the same as the path for
15211         # the test directory
15212         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15213
15214         dir=$(dirname $1)
15215
15216         [[ "${pdir%/}" == "$dir" ]] ||
15217                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15218 }
15219
15220 test_160l() {
15221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15222
15223         remote_mds_nodsh && skip "remote MDS with nodsh"
15224         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15225                 skip "Need MDS version at least 2.13.55"
15226
15227         local cl_user
15228
15229         changelog_register || error "changelog_register failed"
15230         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15231
15232         changelog_users $SINGLEMDS | grep -q $cl_user ||
15233                 error "User '$cl_user' not found in changelog_users"
15234
15235         # Clear some types so that MTIME changelogs are generated
15236         changelog_chmask "-CREAT"
15237         changelog_chmask "-CLOSE"
15238
15239         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15240
15241         # Test CL_MTIME during setattr
15242         touch $DIR/$tdir/$tfile
15243         compare_mtime_changelog $DIR/$tdir/$tfile
15244
15245         # Test CL_MTIME during close
15246         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15247         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15248 }
15249 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15250
15251 test_161a() {
15252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15253
15254         test_mkdir -c1 $DIR/$tdir
15255         cp /etc/hosts $DIR/$tdir/$tfile
15256         test_mkdir -c1 $DIR/$tdir/foo1
15257         test_mkdir -c1 $DIR/$tdir/foo2
15258         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15259         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15260         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15261         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15262         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15263         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15264                 $LFS fid2path $DIR $FID
15265                 error "bad link ea"
15266         fi
15267         # middle
15268         rm $DIR/$tdir/foo2/zachary
15269         # last
15270         rm $DIR/$tdir/foo2/thor
15271         # first
15272         rm $DIR/$tdir/$tfile
15273         # rename
15274         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15275         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15276                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15277         rm $DIR/$tdir/foo2/maggie
15278
15279         # overflow the EA
15280         local longname=$tfile.avg_len_is_thirty_two_
15281         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15282                 error_noexit 'failed to unlink many hardlinks'" EXIT
15283         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15284                 error "failed to hardlink many files"
15285         links=$($LFS fid2path $DIR $FID | wc -l)
15286         echo -n "${links}/1000 links in link EA"
15287         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15288 }
15289 run_test 161a "link ea sanity"
15290
15291 test_161b() {
15292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15293         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15294
15295         local MDTIDX=1
15296         local remote_dir=$DIR/$tdir/remote_dir
15297
15298         mkdir -p $DIR/$tdir
15299         $LFS mkdir -i $MDTIDX $remote_dir ||
15300                 error "create remote directory failed"
15301
15302         cp /etc/hosts $remote_dir/$tfile
15303         mkdir -p $remote_dir/foo1
15304         mkdir -p $remote_dir/foo2
15305         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15306         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15307         ln $remote_dir/$tfile $remote_dir/foo1/luna
15308         ln $remote_dir/$tfile $remote_dir/foo2/thor
15309
15310         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15311                      tr -d ']')
15312         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15313                 $LFS fid2path $DIR $FID
15314                 error "bad link ea"
15315         fi
15316         # middle
15317         rm $remote_dir/foo2/zachary
15318         # last
15319         rm $remote_dir/foo2/thor
15320         # first
15321         rm $remote_dir/$tfile
15322         # rename
15323         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15324         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15325         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15326                 $LFS fid2path $DIR $FID
15327                 error "bad link rename"
15328         fi
15329         rm $remote_dir/foo2/maggie
15330
15331         # overflow the EA
15332         local longname=filename_avg_len_is_thirty_two_
15333         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15334                 error "failed to hardlink many files"
15335         links=$($LFS fid2path $DIR $FID | wc -l)
15336         echo -n "${links}/1000 links in link EA"
15337         [[ ${links} -gt 60 ]] ||
15338                 error "expected at least 60 links in link EA"
15339         unlinkmany $remote_dir/foo2/$longname 1000 ||
15340         error "failed to unlink many hardlinks"
15341 }
15342 run_test 161b "link ea sanity under remote directory"
15343
15344 test_161c() {
15345         remote_mds_nodsh && skip "remote MDS with nodsh"
15346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15347         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15348                 skip "Need MDS version at least 2.1.5"
15349
15350         # define CLF_RENAME_LAST 0x0001
15351         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15352         changelog_register || error "changelog_register failed"
15353
15354         rm -rf $DIR/$tdir
15355         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15356         touch $DIR/$tdir/foo_161c
15357         touch $DIR/$tdir/bar_161c
15358         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15359         changelog_dump | grep RENME | tail -n 5
15360         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15361         changelog_clear 0 || error "changelog_clear failed"
15362         if [ x$flags != "x0x1" ]; then
15363                 error "flag $flags is not 0x1"
15364         fi
15365
15366         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15367         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15368         touch $DIR/$tdir/foo_161c
15369         touch $DIR/$tdir/bar_161c
15370         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15371         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15372         changelog_dump | grep RENME | tail -n 5
15373         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15374         changelog_clear 0 || error "changelog_clear failed"
15375         if [ x$flags != "x0x0" ]; then
15376                 error "flag $flags is not 0x0"
15377         fi
15378         echo "rename overwrite a target having nlink > 1," \
15379                 "changelog record has flags of $flags"
15380
15381         # rename doesn't overwrite a target (changelog flag 0x0)
15382         touch $DIR/$tdir/foo_161c
15383         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15384         changelog_dump | grep RENME | tail -n 5
15385         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15386         changelog_clear 0 || error "changelog_clear failed"
15387         if [ x$flags != "x0x0" ]; then
15388                 error "flag $flags is not 0x0"
15389         fi
15390         echo "rename doesn't overwrite a target," \
15391                 "changelog record has flags of $flags"
15392
15393         # define CLF_UNLINK_LAST 0x0001
15394         # unlink a file having nlink = 1 (changelog flag 0x1)
15395         rm -f $DIR/$tdir/foo2_161c
15396         changelog_dump | grep UNLNK | tail -n 5
15397         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15398         changelog_clear 0 || error "changelog_clear failed"
15399         if [ x$flags != "x0x1" ]; then
15400                 error "flag $flags is not 0x1"
15401         fi
15402         echo "unlink a file having nlink = 1," \
15403                 "changelog record has flags of $flags"
15404
15405         # unlink a file having nlink > 1 (changelog flag 0x0)
15406         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15407         rm -f $DIR/$tdir/foobar_161c
15408         changelog_dump | grep UNLNK | tail -n 5
15409         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15410         changelog_clear 0 || error "changelog_clear failed"
15411         if [ x$flags != "x0x0" ]; then
15412                 error "flag $flags is not 0x0"
15413         fi
15414         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15415 }
15416 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15417
15418 test_161d() {
15419         remote_mds_nodsh && skip "remote MDS with nodsh"
15420         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15421
15422         local pid
15423         local fid
15424
15425         changelog_register || error "changelog_register failed"
15426
15427         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15428         # interfer with $MOUNT/.lustre/fid/ access
15429         mkdir $DIR/$tdir
15430         [[ $? -eq 0 ]] || error "mkdir failed"
15431
15432         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15433         $LCTL set_param fail_loc=0x8000140c
15434         # 5s pause
15435         $LCTL set_param fail_val=5
15436
15437         # create file
15438         echo foofoo > $DIR/$tdir/$tfile &
15439         pid=$!
15440
15441         # wait for create to be delayed
15442         sleep 2
15443
15444         ps -p $pid
15445         [[ $? -eq 0 ]] || error "create should be blocked"
15446
15447         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15448         stack_trap "rm -f $tempfile"
15449         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15450         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15451         # some delay may occur during ChangeLog publishing and file read just
15452         # above, that could allow file write to happen finally
15453         [[ -s $tempfile ]] && echo "file should be empty"
15454
15455         $LCTL set_param fail_loc=0
15456
15457         wait $pid
15458         [[ $? -eq 0 ]] || error "create failed"
15459 }
15460 run_test 161d "create with concurrent .lustre/fid access"
15461
15462 check_path() {
15463         local expected="$1"
15464         shift
15465         local fid="$2"
15466
15467         local path
15468         path=$($LFS fid2path "$@")
15469         local rc=$?
15470
15471         if [ $rc -ne 0 ]; then
15472                 error "path looked up of '$expected' failed: rc=$rc"
15473         elif [ "$path" != "$expected" ]; then
15474                 error "path looked up '$path' instead of '$expected'"
15475         else
15476                 echo "FID '$fid' resolves to path '$path' as expected"
15477         fi
15478 }
15479
15480 test_162a() { # was test_162
15481         test_mkdir -p -c1 $DIR/$tdir/d2
15482         touch $DIR/$tdir/d2/$tfile
15483         touch $DIR/$tdir/d2/x1
15484         touch $DIR/$tdir/d2/x2
15485         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15486         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15487         # regular file
15488         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15489         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15490
15491         # softlink
15492         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15493         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15494         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15495
15496         # softlink to wrong file
15497         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15498         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15499         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15500
15501         # hardlink
15502         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15503         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15504         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15505         # fid2path dir/fsname should both work
15506         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15507         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15508
15509         # hardlink count: check that there are 2 links
15510         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15511         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15512
15513         # hardlink indexing: remove the first link
15514         rm $DIR/$tdir/d2/p/q/r/hlink
15515         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15516 }
15517 run_test 162a "path lookup sanity"
15518
15519 test_162b() {
15520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15522
15523         mkdir $DIR/$tdir
15524         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15525                                 error "create striped dir failed"
15526
15527         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15528                                         tail -n 1 | awk '{print $2}')
15529         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15530
15531         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15532         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15533
15534         # regular file
15535         for ((i=0;i<5;i++)); do
15536                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15537                         error "get fid for f$i failed"
15538                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15539
15540                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15541                         error "get fid for d$i failed"
15542                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15543         done
15544
15545         return 0
15546 }
15547 run_test 162b "striped directory path lookup sanity"
15548
15549 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15550 test_162c() {
15551         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15552                 skip "Need MDS version at least 2.7.51"
15553
15554         local lpath=$tdir.local
15555         local rpath=$tdir.remote
15556
15557         test_mkdir $DIR/$lpath
15558         test_mkdir $DIR/$rpath
15559
15560         for ((i = 0; i <= 101; i++)); do
15561                 lpath="$lpath/$i"
15562                 mkdir $DIR/$lpath
15563                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15564                         error "get fid for local directory $DIR/$lpath failed"
15565                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15566
15567                 rpath="$rpath/$i"
15568                 test_mkdir $DIR/$rpath
15569                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15570                         error "get fid for remote directory $DIR/$rpath failed"
15571                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15572         done
15573
15574         return 0
15575 }
15576 run_test 162c "fid2path works with paths 100 or more directories deep"
15577
15578 oalr_event_count() {
15579         local event="${1}"
15580         local trace="${2}"
15581
15582         awk -v name="${FSNAME}-OST0000" \
15583             -v event="${event}" \
15584             '$1 == "TRACE" && $2 == event && $3 == name' \
15585             "${trace}" |
15586         wc -l
15587 }
15588
15589 oalr_expect_event_count() {
15590         local event="${1}"
15591         local trace="${2}"
15592         local expect="${3}"
15593         local count
15594
15595         count=$(oalr_event_count "${event}" "${trace}")
15596         if ((count == expect)); then
15597                 return 0
15598         fi
15599
15600         error_noexit "${event} event count was '${count}', expected ${expect}"
15601         cat "${trace}" >&2
15602         exit 1
15603 }
15604
15605 cleanup_165() {
15606         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15607         stop ost1
15608         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15609 }
15610
15611 setup_165() {
15612         sync # Flush previous IOs so we can count log entries.
15613         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15614         stack_trap cleanup_165 EXIT
15615 }
15616
15617 test_165a() {
15618         local trace="/tmp/${tfile}.trace"
15619         local rc
15620         local count
15621
15622         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15623                 skip "OFD access log unsupported"
15624
15625         setup_165
15626         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15627         sleep 5
15628
15629         do_facet ost1 ofd_access_log_reader --list
15630         stop ost1
15631
15632         do_facet ost1 killall -TERM ofd_access_log_reader
15633         wait
15634         rc=$?
15635
15636         if ((rc != 0)); then
15637                 error "ofd_access_log_reader exited with rc = '${rc}'"
15638         fi
15639
15640         # Parse trace file for discovery events:
15641         oalr_expect_event_count alr_log_add "${trace}" 1
15642         oalr_expect_event_count alr_log_eof "${trace}" 1
15643         oalr_expect_event_count alr_log_free "${trace}" 1
15644 }
15645 run_test 165a "ofd access log discovery"
15646
15647 test_165b() {
15648         local trace="/tmp/${tfile}.trace"
15649         local file="${DIR}/${tfile}"
15650         local pfid1
15651         local pfid2
15652         local -a entry
15653         local rc
15654         local count
15655         local size
15656         local flags
15657
15658         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15659                 skip "OFD access log unsupported"
15660
15661         setup_165
15662         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15663         sleep 5
15664
15665         do_facet ost1 ofd_access_log_reader --list
15666
15667         lfs setstripe -c 1 -i 0 "${file}"
15668         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15669                 error "cannot create '${file}'"
15670
15671         sleep 5
15672         do_facet ost1 killall -TERM ofd_access_log_reader
15673         wait
15674         rc=$?
15675
15676         if ((rc != 0)); then
15677                 error "ofd_access_log_reader exited with rc = '${rc}'"
15678         fi
15679
15680         oalr_expect_event_count alr_log_entry "${trace}" 1
15681
15682         pfid1=$($LFS path2fid "${file}")
15683
15684         # 1     2             3   4    5     6   7    8    9     10
15685         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15686         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15687
15688         echo "entry = '${entry[*]}'" >&2
15689
15690         pfid2=${entry[4]}
15691         if [[ "${pfid1}" != "${pfid2}" ]]; then
15692                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15693         fi
15694
15695         size=${entry[8]}
15696         if ((size != 1048576)); then
15697                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15698         fi
15699
15700         flags=${entry[10]}
15701         if [[ "${flags}" != "w" ]]; then
15702                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15703         fi
15704
15705         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15706         sleep 5
15707
15708         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15709                 error "cannot read '${file}'"
15710         sleep 5
15711
15712         do_facet ost1 killall -TERM ofd_access_log_reader
15713         wait
15714         rc=$?
15715
15716         if ((rc != 0)); then
15717                 error "ofd_access_log_reader exited with rc = '${rc}'"
15718         fi
15719
15720         oalr_expect_event_count alr_log_entry "${trace}" 1
15721
15722         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15723         echo "entry = '${entry[*]}'" >&2
15724
15725         pfid2=${entry[4]}
15726         if [[ "${pfid1}" != "${pfid2}" ]]; then
15727                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15728         fi
15729
15730         size=${entry[8]}
15731         if ((size != 524288)); then
15732                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15733         fi
15734
15735         flags=${entry[10]}
15736         if [[ "${flags}" != "r" ]]; then
15737                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15738         fi
15739 }
15740 run_test 165b "ofd access log entries are produced and consumed"
15741
15742 test_165c() {
15743         local trace="/tmp/${tfile}.trace"
15744         local file="${DIR}/${tdir}/${tfile}"
15745
15746         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15747                 skip "OFD access log unsupported"
15748
15749         test_mkdir "${DIR}/${tdir}"
15750
15751         setup_165
15752         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15753         sleep 5
15754
15755         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15756
15757         # 4096 / 64 = 64. Create twice as many entries.
15758         for ((i = 0; i < 128; i++)); do
15759                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15760                         error "cannot create file"
15761         done
15762
15763         sync
15764
15765         do_facet ost1 killall -TERM ofd_access_log_reader
15766         wait
15767         rc=$?
15768         if ((rc != 0)); then
15769                 error "ofd_access_log_reader exited with rc = '${rc}'"
15770         fi
15771
15772         unlinkmany  "${file}-%d" 128
15773 }
15774 run_test 165c "full ofd access logs do not block IOs"
15775
15776 oal_get_read_count() {
15777         local stats="$1"
15778
15779         # STATS lustre-OST0001 alr_read_count 1
15780
15781         do_facet ost1 cat "${stats}" |
15782         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15783              END { print count; }'
15784 }
15785
15786 oal_expect_read_count() {
15787         local stats="$1"
15788         local count
15789         local expect="$2"
15790
15791         # Ask ofd_access_log_reader to write stats.
15792         do_facet ost1 killall -USR1 ofd_access_log_reader
15793
15794         # Allow some time for things to happen.
15795         sleep 1
15796
15797         count=$(oal_get_read_count "${stats}")
15798         if ((count == expect)); then
15799                 return 0
15800         fi
15801
15802         error_noexit "bad read count, got ${count}, expected ${expect}"
15803         do_facet ost1 cat "${stats}" >&2
15804         exit 1
15805 }
15806
15807 test_165d() {
15808         local stats="/tmp/${tfile}.stats"
15809         local file="${DIR}/${tdir}/${tfile}"
15810         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15811
15812         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15813                 skip "OFD access log unsupported"
15814
15815         test_mkdir "${DIR}/${tdir}"
15816
15817         setup_165
15818         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15819         sleep 5
15820
15821         lfs setstripe -c 1 -i 0 "${file}"
15822
15823         do_facet ost1 lctl set_param "${param}=rw"
15824         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15825                 error "cannot create '${file}'"
15826         oal_expect_read_count "${stats}" 1
15827
15828         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15829                 error "cannot read '${file}'"
15830         oal_expect_read_count "${stats}" 2
15831
15832         do_facet ost1 lctl set_param "${param}=r"
15833         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15834                 error "cannot create '${file}'"
15835         oal_expect_read_count "${stats}" 2
15836
15837         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15838                 error "cannot read '${file}'"
15839         oal_expect_read_count "${stats}" 3
15840
15841         do_facet ost1 lctl set_param "${param}=w"
15842         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15843                 error "cannot create '${file}'"
15844         oal_expect_read_count "${stats}" 4
15845
15846         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15847                 error "cannot read '${file}'"
15848         oal_expect_read_count "${stats}" 4
15849
15850         do_facet ost1 lctl set_param "${param}=0"
15851         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15852                 error "cannot create '${file}'"
15853         oal_expect_read_count "${stats}" 4
15854
15855         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15856                 error "cannot read '${file}'"
15857         oal_expect_read_count "${stats}" 4
15858
15859         do_facet ost1 killall -TERM ofd_access_log_reader
15860         wait
15861         rc=$?
15862         if ((rc != 0)); then
15863                 error "ofd_access_log_reader exited with rc = '${rc}'"
15864         fi
15865 }
15866 run_test 165d "ofd_access_log mask works"
15867
15868 test_165e() {
15869         local stats="/tmp/${tfile}.stats"
15870         local file0="${DIR}/${tdir}-0/${tfile}"
15871         local file1="${DIR}/${tdir}-1/${tfile}"
15872
15873         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15874                 skip "OFD access log unsupported"
15875
15876         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15877
15878         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15879         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15880
15881         lfs setstripe -c 1 -i 0 "${file0}"
15882         lfs setstripe -c 1 -i 0 "${file1}"
15883
15884         setup_165
15885         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15886         sleep 5
15887
15888         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15889                 error "cannot create '${file0}'"
15890         sync
15891         oal_expect_read_count "${stats}" 0
15892
15893         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15894                 error "cannot create '${file1}'"
15895         sync
15896         oal_expect_read_count "${stats}" 1
15897
15898         do_facet ost1 killall -TERM ofd_access_log_reader
15899         wait
15900         rc=$?
15901         if ((rc != 0)); then
15902                 error "ofd_access_log_reader exited with rc = '${rc}'"
15903         fi
15904 }
15905 run_test 165e "ofd_access_log MDT index filter works"
15906
15907 test_165f() {
15908         local trace="/tmp/${tfile}.trace"
15909         local rc
15910         local count
15911
15912         setup_165
15913         do_facet ost1 timeout 60 ofd_access_log_reader \
15914                 --exit-on-close --debug=- --trace=- > "${trace}" &
15915         sleep 5
15916         stop ost1
15917
15918         wait
15919         rc=$?
15920
15921         if ((rc != 0)); then
15922                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15923                 cat "${trace}"
15924                 exit 1
15925         fi
15926 }
15927 run_test 165f "ofd_access_log_reader --exit-on-close works"
15928
15929 test_169() {
15930         # do directio so as not to populate the page cache
15931         log "creating a 10 Mb file"
15932         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15933                 error "multiop failed while creating a file"
15934         log "starting reads"
15935         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15936         log "truncating the file"
15937         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15938                 error "multiop failed while truncating the file"
15939         log "killing dd"
15940         kill %+ || true # reads might have finished
15941         echo "wait until dd is finished"
15942         wait
15943         log "removing the temporary file"
15944         rm -rf $DIR/$tfile || error "tmp file removal failed"
15945 }
15946 run_test 169 "parallel read and truncate should not deadlock"
15947
15948 test_170() {
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950
15951         $LCTL clear     # bug 18514
15952         $LCTL debug_daemon start $TMP/${tfile}_log_good
15953         touch $DIR/$tfile
15954         $LCTL debug_daemon stop
15955         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15956                 error "sed failed to read log_good"
15957
15958         $LCTL debug_daemon start $TMP/${tfile}_log_good
15959         rm -rf $DIR/$tfile
15960         $LCTL debug_daemon stop
15961
15962         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15963                error "lctl df log_bad failed"
15964
15965         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15966         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15967
15968         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15969         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15970
15971         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15972                 error "bad_line good_line1 good_line2 are empty"
15973
15974         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15975         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15976         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15977
15978         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15979         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15980         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15981
15982         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15983                 error "bad_line_new good_line_new are empty"
15984
15985         local expected_good=$((good_line1 + good_line2*2))
15986
15987         rm -f $TMP/${tfile}*
15988         # LU-231, short malformed line may not be counted into bad lines
15989         if [ $bad_line -ne $bad_line_new ] &&
15990                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15991                 error "expected $bad_line bad lines, but got $bad_line_new"
15992                 return 1
15993         fi
15994
15995         if [ $expected_good -ne $good_line_new ]; then
15996                 error "expected $expected_good good lines, but got $good_line_new"
15997                 return 2
15998         fi
15999         true
16000 }
16001 run_test 170 "test lctl df to handle corrupted log ====================="
16002
16003 test_171() { # bug20592
16004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16005
16006         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16007         $LCTL set_param fail_loc=0x50e
16008         $LCTL set_param fail_val=3000
16009         multiop_bg_pause $DIR/$tfile O_s || true
16010         local MULTIPID=$!
16011         kill -USR1 $MULTIPID
16012         # cause log dump
16013         sleep 3
16014         wait $MULTIPID
16015         if dmesg | grep "recursive fault"; then
16016                 error "caught a recursive fault"
16017         fi
16018         $LCTL set_param fail_loc=0
16019         true
16020 }
16021 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16022
16023 # it would be good to share it with obdfilter-survey/iokit-libecho code
16024 setup_obdecho_osc () {
16025         local rc=0
16026         local ost_nid=$1
16027         local obdfilter_name=$2
16028         echo "Creating new osc for $obdfilter_name on $ost_nid"
16029         # make sure we can find loopback nid
16030         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16031
16032         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16033                            ${obdfilter_name}_osc_UUID || rc=2; }
16034         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16035                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16036         return $rc
16037 }
16038
16039 cleanup_obdecho_osc () {
16040         local obdfilter_name=$1
16041         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16042         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16043         return 0
16044 }
16045
16046 obdecho_test() {
16047         local OBD=$1
16048         local node=$2
16049         local pages=${3:-64}
16050         local rc=0
16051         local id
16052
16053         local count=10
16054         local obd_size=$(get_obd_size $node $OBD)
16055         local page_size=$(get_page_size $node)
16056         if [[ -n "$obd_size" ]]; then
16057                 local new_count=$((obd_size / (pages * page_size / 1024)))
16058                 [[ $new_count -ge $count ]] || count=$new_count
16059         fi
16060
16061         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16062         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16063                            rc=2; }
16064         if [ $rc -eq 0 ]; then
16065             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16066             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16067         fi
16068         echo "New object id is $id"
16069         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16070                            rc=4; }
16071         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16072                            "test_brw $count w v $pages $id" || rc=4; }
16073         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16074                            rc=4; }
16075         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16076                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16077         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16078                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16079         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16080         return $rc
16081 }
16082
16083 test_180a() {
16084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16085
16086         if ! [ -d /sys/fs/lustre/echo_client ] &&
16087            ! module_loaded obdecho; then
16088                 load_module obdecho/obdecho &&
16089                         stack_trap "rmmod obdecho" EXIT ||
16090                         error "unable to load obdecho on client"
16091         fi
16092
16093         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16094         local host=$($LCTL get_param -n osc.$osc.import |
16095                      awk '/current_connection:/ { print $2 }' )
16096         local target=$($LCTL get_param -n osc.$osc.import |
16097                        awk '/target:/ { print $2 }' )
16098         target=${target%_UUID}
16099
16100         if [ -n "$target" ]; then
16101                 setup_obdecho_osc $host $target &&
16102                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16103                         { error "obdecho setup failed with $?"; return; }
16104
16105                 obdecho_test ${target}_osc client ||
16106                         error "obdecho_test failed on ${target}_osc"
16107         else
16108                 $LCTL get_param osc.$osc.import
16109                 error "there is no osc.$osc.import target"
16110         fi
16111 }
16112 run_test 180a "test obdecho on osc"
16113
16114 test_180b() {
16115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16116         remote_ost_nodsh && skip "remote OST with nodsh"
16117
16118         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16119                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16120                 error "failed to load module obdecho"
16121
16122         local target=$(do_facet ost1 $LCTL dl |
16123                        awk '/obdfilter/ { print $4; exit; }')
16124
16125         if [ -n "$target" ]; then
16126                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16127         else
16128                 do_facet ost1 $LCTL dl
16129                 error "there is no obdfilter target on ost1"
16130         fi
16131 }
16132 run_test 180b "test obdecho directly on obdfilter"
16133
16134 test_180c() { # LU-2598
16135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16136         remote_ost_nodsh && skip "remote OST with nodsh"
16137         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16138                 skip "Need MDS version at least 2.4.0"
16139
16140         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16141                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16142                 error "failed to load module obdecho"
16143
16144         local target=$(do_facet ost1 $LCTL dl |
16145                        awk '/obdfilter/ { print $4; exit; }')
16146
16147         if [ -n "$target" ]; then
16148                 local pages=16384 # 64MB bulk I/O RPC size
16149
16150                 obdecho_test "$target" ost1 "$pages" ||
16151                         error "obdecho_test with pages=$pages failed with $?"
16152         else
16153                 do_facet ost1 $LCTL dl
16154                 error "there is no obdfilter target on ost1"
16155         fi
16156 }
16157 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16158
16159 test_181() { # bug 22177
16160         test_mkdir $DIR/$tdir
16161         # create enough files to index the directory
16162         createmany -o $DIR/$tdir/foobar 4000
16163         # print attributes for debug purpose
16164         lsattr -d .
16165         # open dir
16166         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16167         MULTIPID=$!
16168         # remove the files & current working dir
16169         unlinkmany $DIR/$tdir/foobar 4000
16170         rmdir $DIR/$tdir
16171         kill -USR1 $MULTIPID
16172         wait $MULTIPID
16173         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16174         return 0
16175 }
16176 run_test 181 "Test open-unlinked dir ========================"
16177
16178 test_182() {
16179         local fcount=1000
16180         local tcount=10
16181
16182         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16183
16184         $LCTL set_param mdc.*.rpc_stats=clear
16185
16186         for (( i = 0; i < $tcount; i++ )) ; do
16187                 mkdir $DIR/$tdir/$i
16188         done
16189
16190         for (( i = 0; i < $tcount; i++ )) ; do
16191                 createmany -o $DIR/$tdir/$i/f- $fcount &
16192         done
16193         wait
16194
16195         for (( i = 0; i < $tcount; i++ )) ; do
16196                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16197         done
16198         wait
16199
16200         $LCTL get_param mdc.*.rpc_stats
16201
16202         rm -rf $DIR/$tdir
16203 }
16204 run_test 182 "Test parallel modify metadata operations ================"
16205
16206 test_183() { # LU-2275
16207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16208         remote_mds_nodsh && skip "remote MDS with nodsh"
16209         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16210                 skip "Need MDS version at least 2.3.56"
16211
16212         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16213         echo aaa > $DIR/$tdir/$tfile
16214
16215 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16216         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16217
16218         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16219         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16220
16221         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16222
16223         # Flush negative dentry cache
16224         touch $DIR/$tdir/$tfile
16225
16226         # We are not checking for any leaked references here, they'll
16227         # become evident next time we do cleanup with module unload.
16228         rm -rf $DIR/$tdir
16229 }
16230 run_test 183 "No crash or request leak in case of strange dispositions ========"
16231
16232 # test suite 184 is for LU-2016, LU-2017
16233 test_184a() {
16234         check_swap_layouts_support
16235
16236         dir0=$DIR/$tdir/$testnum
16237         test_mkdir -p -c1 $dir0
16238         ref1=/etc/passwd
16239         ref2=/etc/group
16240         file1=$dir0/f1
16241         file2=$dir0/f2
16242         $LFS setstripe -c1 $file1
16243         cp $ref1 $file1
16244         $LFS setstripe -c2 $file2
16245         cp $ref2 $file2
16246         gen1=$($LFS getstripe -g $file1)
16247         gen2=$($LFS getstripe -g $file2)
16248
16249         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16250         gen=$($LFS getstripe -g $file1)
16251         [[ $gen1 != $gen ]] ||
16252                 "Layout generation on $file1 does not change"
16253         gen=$($LFS getstripe -g $file2)
16254         [[ $gen2 != $gen ]] ||
16255                 "Layout generation on $file2 does not change"
16256
16257         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16258         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16259
16260         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16261 }
16262 run_test 184a "Basic layout swap"
16263
16264 test_184b() {
16265         check_swap_layouts_support
16266
16267         dir0=$DIR/$tdir/$testnum
16268         mkdir -p $dir0 || error "creating dir $dir0"
16269         file1=$dir0/f1
16270         file2=$dir0/f2
16271         file3=$dir0/f3
16272         dir1=$dir0/d1
16273         dir2=$dir0/d2
16274         mkdir $dir1 $dir2
16275         $LFS setstripe -c1 $file1
16276         $LFS setstripe -c2 $file2
16277         $LFS setstripe -c1 $file3
16278         chown $RUNAS_ID $file3
16279         gen1=$($LFS getstripe -g $file1)
16280         gen2=$($LFS getstripe -g $file2)
16281
16282         $LFS swap_layouts $dir1 $dir2 &&
16283                 error "swap of directories layouts should fail"
16284         $LFS swap_layouts $dir1 $file1 &&
16285                 error "swap of directory and file layouts should fail"
16286         $RUNAS $LFS swap_layouts $file1 $file2 &&
16287                 error "swap of file we cannot write should fail"
16288         $LFS swap_layouts $file1 $file3 &&
16289                 error "swap of file with different owner should fail"
16290         /bin/true # to clear error code
16291 }
16292 run_test 184b "Forbidden layout swap (will generate errors)"
16293
16294 test_184c() {
16295         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16296         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16297         check_swap_layouts_support
16298         check_swap_layout_no_dom $DIR
16299
16300         local dir0=$DIR/$tdir/$testnum
16301         mkdir -p $dir0 || error "creating dir $dir0"
16302
16303         local ref1=$dir0/ref1
16304         local ref2=$dir0/ref2
16305         local file1=$dir0/file1
16306         local file2=$dir0/file2
16307         # create a file large enough for the concurrent test
16308         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16309         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16310         echo "ref file size: ref1($(stat -c %s $ref1))," \
16311              "ref2($(stat -c %s $ref2))"
16312
16313         cp $ref2 $file2
16314         dd if=$ref1 of=$file1 bs=16k &
16315         local DD_PID=$!
16316
16317         # Make sure dd starts to copy file, but wait at most 5 seconds
16318         local loops=0
16319         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16320
16321         $LFS swap_layouts $file1 $file2
16322         local rc=$?
16323         wait $DD_PID
16324         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16325         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16326
16327         # how many bytes copied before swapping layout
16328         local copied=$(stat -c %s $file2)
16329         local remaining=$(stat -c %s $ref1)
16330         remaining=$((remaining - copied))
16331         echo "Copied $copied bytes before swapping layout..."
16332
16333         cmp -n $copied $file1 $ref2 | grep differ &&
16334                 error "Content mismatch [0, $copied) of ref2 and file1"
16335         cmp -n $copied $file2 $ref1 ||
16336                 error "Content mismatch [0, $copied) of ref1 and file2"
16337         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16338                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16339
16340         # clean up
16341         rm -f $ref1 $ref2 $file1 $file2
16342 }
16343 run_test 184c "Concurrent write and layout swap"
16344
16345 test_184d() {
16346         check_swap_layouts_support
16347         check_swap_layout_no_dom $DIR
16348         [ -z "$(which getfattr 2>/dev/null)" ] &&
16349                 skip_env "no getfattr command"
16350
16351         local file1=$DIR/$tdir/$tfile-1
16352         local file2=$DIR/$tdir/$tfile-2
16353         local file3=$DIR/$tdir/$tfile-3
16354         local lovea1
16355         local lovea2
16356
16357         mkdir -p $DIR/$tdir
16358         touch $file1 || error "create $file1 failed"
16359         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16360                 error "create $file2 failed"
16361         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16362                 error "create $file3 failed"
16363         lovea1=$(get_layout_param $file1)
16364
16365         $LFS swap_layouts $file2 $file3 ||
16366                 error "swap $file2 $file3 layouts failed"
16367         $LFS swap_layouts $file1 $file2 ||
16368                 error "swap $file1 $file2 layouts failed"
16369
16370         lovea2=$(get_layout_param $file2)
16371         echo "$lovea1"
16372         echo "$lovea2"
16373         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16374
16375         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16376         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16377 }
16378 run_test 184d "allow stripeless layouts swap"
16379
16380 test_184e() {
16381         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16382                 skip "Need MDS version at least 2.6.94"
16383         check_swap_layouts_support
16384         check_swap_layout_no_dom $DIR
16385         [ -z "$(which getfattr 2>/dev/null)" ] &&
16386                 skip_env "no getfattr command"
16387
16388         local file1=$DIR/$tdir/$tfile-1
16389         local file2=$DIR/$tdir/$tfile-2
16390         local file3=$DIR/$tdir/$tfile-3
16391         local lovea
16392
16393         mkdir -p $DIR/$tdir
16394         touch $file1 || error "create $file1 failed"
16395         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16396                 error "create $file2 failed"
16397         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16398                 error "create $file3 failed"
16399
16400         $LFS swap_layouts $file1 $file2 ||
16401                 error "swap $file1 $file2 layouts failed"
16402
16403         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16404         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16405
16406         echo 123 > $file1 || error "Should be able to write into $file1"
16407
16408         $LFS swap_layouts $file1 $file3 ||
16409                 error "swap $file1 $file3 layouts failed"
16410
16411         echo 123 > $file1 || error "Should be able to write into $file1"
16412
16413         rm -rf $file1 $file2 $file3
16414 }
16415 run_test 184e "Recreate layout after stripeless layout swaps"
16416
16417 test_184f() {
16418         # Create a file with name longer than sizeof(struct stat) ==
16419         # 144 to see if we can get chars from the file name to appear
16420         # in the returned striping. Note that 'f' == 0x66.
16421         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16422
16423         mkdir -p $DIR/$tdir
16424         mcreate $DIR/$tdir/$file
16425         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16426                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16427         fi
16428 }
16429 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16430
16431 test_185() { # LU-2441
16432         # LU-3553 - no volatile file support in old servers
16433         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16434                 skip "Need MDS version at least 2.3.60"
16435
16436         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16437         touch $DIR/$tdir/spoo
16438         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16439         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16440                 error "cannot create/write a volatile file"
16441         [ "$FILESET" == "" ] &&
16442         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16443                 error "FID is still valid after close"
16444
16445         multiop_bg_pause $DIR/$tdir vVw4096_c
16446         local multi_pid=$!
16447
16448         local OLD_IFS=$IFS
16449         IFS=":"
16450         local fidv=($fid)
16451         IFS=$OLD_IFS
16452         # assume that the next FID for this client is sequential, since stdout
16453         # is unfortunately eaten by multiop_bg_pause
16454         local n=$((${fidv[1]} + 1))
16455         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16456         if [ "$FILESET" == "" ]; then
16457                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16458                         error "FID is missing before close"
16459         fi
16460         kill -USR1 $multi_pid
16461         # 1 second delay, so if mtime change we will see it
16462         sleep 1
16463         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16464         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16465 }
16466 run_test 185 "Volatile file support"
16467
16468 function create_check_volatile() {
16469         local idx=$1
16470         local tgt
16471
16472         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16473         local PID=$!
16474         sleep 1
16475         local FID=$(cat /tmp/${tfile}.fid)
16476         [ "$FID" == "" ] && error "can't get FID for volatile"
16477         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16478         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16479         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16480         kill -USR1 $PID
16481         wait
16482         sleep 1
16483         cancel_lru_locks mdc # flush opencache
16484         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16485         return 0
16486 }
16487
16488 test_185a(){
16489         # LU-12516 - volatile creation via .lustre
16490         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16491                 skip "Need MDS version at least 2.3.55"
16492
16493         create_check_volatile 0
16494         [ $MDSCOUNT -lt 2 ] && return 0
16495
16496         # DNE case
16497         create_check_volatile 1
16498
16499         return 0
16500 }
16501 run_test 185a "Volatile file creation in .lustre/fid/"
16502
16503 test_187a() {
16504         remote_mds_nodsh && skip "remote MDS with nodsh"
16505         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16506                 skip "Need MDS version at least 2.3.0"
16507
16508         local dir0=$DIR/$tdir/$testnum
16509         mkdir -p $dir0 || error "creating dir $dir0"
16510
16511         local file=$dir0/file1
16512         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16513         local dv1=$($LFS data_version $file)
16514         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16515         local dv2=$($LFS data_version $file)
16516         [[ $dv1 != $dv2 ]] ||
16517                 error "data version did not change on write $dv1 == $dv2"
16518
16519         # clean up
16520         rm -f $file1
16521 }
16522 run_test 187a "Test data version change"
16523
16524 test_187b() {
16525         remote_mds_nodsh && skip "remote MDS with nodsh"
16526         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16527                 skip "Need MDS version at least 2.3.0"
16528
16529         local dir0=$DIR/$tdir/$testnum
16530         mkdir -p $dir0 || error "creating dir $dir0"
16531
16532         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16533         [[ ${DV[0]} != ${DV[1]} ]] ||
16534                 error "data version did not change on write"\
16535                       " ${DV[0]} == ${DV[1]}"
16536
16537         # clean up
16538         rm -f $file1
16539 }
16540 run_test 187b "Test data version change on volatile file"
16541
16542 test_200() {
16543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16544         remote_mgs_nodsh && skip "remote MGS with nodsh"
16545         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16546
16547         local POOL=${POOL:-cea1}
16548         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16549         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16550         # Pool OST targets
16551         local first_ost=0
16552         local last_ost=$(($OSTCOUNT - 1))
16553         local ost_step=2
16554         local ost_list=$(seq $first_ost $ost_step $last_ost)
16555         local ost_range="$first_ost $last_ost $ost_step"
16556         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16557         local file_dir=$POOL_ROOT/file_tst
16558         local subdir=$test_path/subdir
16559         local rc=0
16560
16561         while : ; do
16562                 # former test_200a test_200b
16563                 pool_add $POOL                          || { rc=$? ; break; }
16564                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16565                 # former test_200c test_200d
16566                 mkdir -p $test_path
16567                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16568                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16569                 mkdir -p $subdir
16570                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16571                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16572                                                         || { rc=$? ; break; }
16573                 # former test_200e test_200f
16574                 local files=$((OSTCOUNT*3))
16575                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16576                                                         || { rc=$? ; break; }
16577                 pool_create_files $POOL $file_dir $files "$ost_list" \
16578                                                         || { rc=$? ; break; }
16579                 # former test_200g test_200h
16580                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16581                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16582
16583                 # former test_201a test_201b test_201c
16584                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16585
16586                 local f=$test_path/$tfile
16587                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16588                 pool_remove $POOL $f                    || { rc=$? ; break; }
16589                 break
16590         done
16591
16592         destroy_test_pools
16593
16594         return $rc
16595 }
16596 run_test 200 "OST pools"
16597
16598 # usage: default_attr <count | size | offset>
16599 default_attr() {
16600         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16601 }
16602
16603 # usage: check_default_stripe_attr
16604 check_default_stripe_attr() {
16605         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16606         case $1 in
16607         --stripe-count|-c)
16608                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16609         --stripe-size|-S)
16610                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16611         --stripe-index|-i)
16612                 EXPECTED=-1;;
16613         *)
16614                 error "unknown getstripe attr '$1'"
16615         esac
16616
16617         [ $ACTUAL == $EXPECTED ] ||
16618                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16619 }
16620
16621 test_204a() {
16622         test_mkdir $DIR/$tdir
16623         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16624
16625         check_default_stripe_attr --stripe-count
16626         check_default_stripe_attr --stripe-size
16627         check_default_stripe_attr --stripe-index
16628 }
16629 run_test 204a "Print default stripe attributes"
16630
16631 test_204b() {
16632         test_mkdir $DIR/$tdir
16633         $LFS setstripe --stripe-count 1 $DIR/$tdir
16634
16635         check_default_stripe_attr --stripe-size
16636         check_default_stripe_attr --stripe-index
16637 }
16638 run_test 204b "Print default stripe size and offset"
16639
16640 test_204c() {
16641         test_mkdir $DIR/$tdir
16642         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16643
16644         check_default_stripe_attr --stripe-count
16645         check_default_stripe_attr --stripe-index
16646 }
16647 run_test 204c "Print default stripe count and offset"
16648
16649 test_204d() {
16650         test_mkdir $DIR/$tdir
16651         $LFS setstripe --stripe-index 0 $DIR/$tdir
16652
16653         check_default_stripe_attr --stripe-count
16654         check_default_stripe_attr --stripe-size
16655 }
16656 run_test 204d "Print default stripe count and size"
16657
16658 test_204e() {
16659         test_mkdir $DIR/$tdir
16660         $LFS setstripe -d $DIR/$tdir
16661
16662         check_default_stripe_attr --stripe-count --raw
16663         check_default_stripe_attr --stripe-size --raw
16664         check_default_stripe_attr --stripe-index --raw
16665 }
16666 run_test 204e "Print raw stripe attributes"
16667
16668 test_204f() {
16669         test_mkdir $DIR/$tdir
16670         $LFS setstripe --stripe-count 1 $DIR/$tdir
16671
16672         check_default_stripe_attr --stripe-size --raw
16673         check_default_stripe_attr --stripe-index --raw
16674 }
16675 run_test 204f "Print raw stripe size and offset"
16676
16677 test_204g() {
16678         test_mkdir $DIR/$tdir
16679         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16680
16681         check_default_stripe_attr --stripe-count --raw
16682         check_default_stripe_attr --stripe-index --raw
16683 }
16684 run_test 204g "Print raw stripe count and offset"
16685
16686 test_204h() {
16687         test_mkdir $DIR/$tdir
16688         $LFS setstripe --stripe-index 0 $DIR/$tdir
16689
16690         check_default_stripe_attr --stripe-count --raw
16691         check_default_stripe_attr --stripe-size --raw
16692 }
16693 run_test 204h "Print raw stripe count and size"
16694
16695 # Figure out which job scheduler is being used, if any,
16696 # or use a fake one
16697 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16698         JOBENV=SLURM_JOB_ID
16699 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16700         JOBENV=LSB_JOBID
16701 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16702         JOBENV=PBS_JOBID
16703 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16704         JOBENV=LOADL_STEP_ID
16705 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16706         JOBENV=JOB_ID
16707 else
16708         $LCTL list_param jobid_name > /dev/null 2>&1
16709         if [ $? -eq 0 ]; then
16710                 JOBENV=nodelocal
16711         else
16712                 JOBENV=FAKE_JOBID
16713         fi
16714 fi
16715 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16716
16717 verify_jobstats() {
16718         local cmd=($1)
16719         shift
16720         local facets="$@"
16721
16722 # we don't really need to clear the stats for this test to work, since each
16723 # command has a unique jobid, but it makes debugging easier if needed.
16724 #       for facet in $facets; do
16725 #               local dev=$(convert_facet2label $facet)
16726 #               # clear old jobstats
16727 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16728 #       done
16729
16730         # use a new JobID for each test, or we might see an old one
16731         [ "$JOBENV" = "FAKE_JOBID" ] &&
16732                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16733
16734         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16735
16736         [ "$JOBENV" = "nodelocal" ] && {
16737                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16738                 $LCTL set_param jobid_name=$FAKE_JOBID
16739                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16740         }
16741
16742         log "Test: ${cmd[*]}"
16743         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16744
16745         if [ $JOBENV = "FAKE_JOBID" ]; then
16746                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16747         else
16748                 ${cmd[*]}
16749         fi
16750
16751         # all files are created on OST0000
16752         for facet in $facets; do
16753                 local stats="*.$(convert_facet2label $facet).job_stats"
16754
16755                 # strip out libtool wrappers for in-tree executables
16756                 if [ $(do_facet $facet lctl get_param $stats |
16757                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16758                         do_facet $facet lctl get_param $stats
16759                         error "No jobstats for $JOBVAL found on $facet::$stats"
16760                 fi
16761         done
16762 }
16763
16764 jobstats_set() {
16765         local new_jobenv=$1
16766
16767         set_persistent_param_and_check client "jobid_var" \
16768                 "$FSNAME.sys.jobid_var" $new_jobenv
16769 }
16770
16771 test_205a() { # Job stats
16772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16773         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16774                 skip "Need MDS version with at least 2.7.1"
16775         remote_mgs_nodsh && skip "remote MGS with nodsh"
16776         remote_mds_nodsh && skip "remote MDS with nodsh"
16777         remote_ost_nodsh && skip "remote OST with nodsh"
16778         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16779                 skip "Server doesn't support jobstats"
16780         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16781
16782         local old_jobenv=$($LCTL get_param -n jobid_var)
16783         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16784
16785         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16786                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16787         else
16788                 stack_trap "do_facet mgs $PERM_CMD \
16789                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16790         fi
16791         changelog_register
16792
16793         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16794                                 mdt.*.job_cleanup_interval | head -n 1)
16795         local new_interval=5
16796         do_facet $SINGLEMDS \
16797                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16798         stack_trap "do_facet $SINGLEMDS \
16799                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16800         local start=$SECONDS
16801
16802         local cmd
16803         # mkdir
16804         cmd="mkdir $DIR/$tdir"
16805         verify_jobstats "$cmd" "$SINGLEMDS"
16806         # rmdir
16807         cmd="rmdir $DIR/$tdir"
16808         verify_jobstats "$cmd" "$SINGLEMDS"
16809         # mkdir on secondary MDT
16810         if [ $MDSCOUNT -gt 1 ]; then
16811                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16812                 verify_jobstats "$cmd" "mds2"
16813         fi
16814         # mknod
16815         cmd="mknod $DIR/$tfile c 1 3"
16816         verify_jobstats "$cmd" "$SINGLEMDS"
16817         # unlink
16818         cmd="rm -f $DIR/$tfile"
16819         verify_jobstats "$cmd" "$SINGLEMDS"
16820         # create all files on OST0000 so verify_jobstats can find OST stats
16821         # open & close
16822         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16823         verify_jobstats "$cmd" "$SINGLEMDS"
16824         # setattr
16825         cmd="touch $DIR/$tfile"
16826         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16827         # write
16828         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16829         verify_jobstats "$cmd" "ost1"
16830         # read
16831         cancel_lru_locks osc
16832         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16833         verify_jobstats "$cmd" "ost1"
16834         # truncate
16835         cmd="$TRUNCATE $DIR/$tfile 0"
16836         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16837         # rename
16838         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16839         verify_jobstats "$cmd" "$SINGLEMDS"
16840         # jobstats expiry - sleep until old stats should be expired
16841         local left=$((new_interval + 5 - (SECONDS - start)))
16842         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16843                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16844                         "0" $left
16845         cmd="mkdir $DIR/$tdir.expire"
16846         verify_jobstats "$cmd" "$SINGLEMDS"
16847         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16848             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16849
16850         # Ensure that jobid are present in changelog (if supported by MDS)
16851         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16852                 changelog_dump | tail -10
16853                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16854                 [ $jobids -eq 9 ] ||
16855                         error "Wrong changelog jobid count $jobids != 9"
16856
16857                 # LU-5862
16858                 JOBENV="disable"
16859                 jobstats_set $JOBENV
16860                 touch $DIR/$tfile
16861                 changelog_dump | grep $tfile
16862                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16863                 [ $jobids -eq 0 ] ||
16864                         error "Unexpected jobids when jobid_var=$JOBENV"
16865         fi
16866
16867         # test '%j' access to environment variable - if supported
16868         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16869                 JOBENV="JOBCOMPLEX"
16870                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16871
16872                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16873         fi
16874
16875         # test '%j' access to per-session jobid - if supported
16876         if lctl list_param jobid_this_session > /dev/null 2>&1
16877         then
16878                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16879                 lctl set_param jobid_this_session=$USER
16880
16881                 JOBENV="JOBCOMPLEX"
16882                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16883
16884                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16885         fi
16886 }
16887 run_test 205a "Verify job stats"
16888
16889 # LU-13117, LU-13597
16890 test_205b() {
16891         job_stats="mdt.*.job_stats"
16892         $LCTL set_param $job_stats=clear
16893         # Setting jobid_var to USER might not be supported
16894         $LCTL set_param jobid_var=USER || true
16895         $LCTL set_param jobid_name="%e.%u"
16896         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16897         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16898                 grep "job_id:.*foolish" &&
16899                         error "Unexpected jobid found"
16900         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16901                 grep "open:.*min.*max.*sum" ||
16902                         error "wrong job_stats format found"
16903 }
16904 run_test 205b "Verify job stats jobid and output format"
16905
16906 # LU-13733
16907 test_205c() {
16908         $LCTL set_param llite.*.stats=0
16909         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16910         $LCTL get_param llite.*.stats
16911         $LCTL get_param llite.*.stats | grep \
16912                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16913                         error "wrong client stats format found"
16914 }
16915 run_test 205c "Verify client stats format"
16916
16917 # LU-1480, LU-1773 and LU-1657
16918 test_206() {
16919         mkdir -p $DIR/$tdir
16920         $LFS setstripe -c -1 $DIR/$tdir
16921 #define OBD_FAIL_LOV_INIT 0x1403
16922         $LCTL set_param fail_loc=0xa0001403
16923         $LCTL set_param fail_val=1
16924         touch $DIR/$tdir/$tfile || true
16925 }
16926 run_test 206 "fail lov_init_raid0() doesn't lbug"
16927
16928 test_207a() {
16929         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16930         local fsz=`stat -c %s $DIR/$tfile`
16931         cancel_lru_locks mdc
16932
16933         # do not return layout in getattr intent
16934 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16935         $LCTL set_param fail_loc=0x170
16936         local sz=`stat -c %s $DIR/$tfile`
16937
16938         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16939
16940         rm -rf $DIR/$tfile
16941 }
16942 run_test 207a "can refresh layout at glimpse"
16943
16944 test_207b() {
16945         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16946         local cksum=`md5sum $DIR/$tfile`
16947         local fsz=`stat -c %s $DIR/$tfile`
16948         cancel_lru_locks mdc
16949         cancel_lru_locks osc
16950
16951         # do not return layout in getattr intent
16952 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16953         $LCTL set_param fail_loc=0x171
16954
16955         # it will refresh layout after the file is opened but before read issues
16956         echo checksum is "$cksum"
16957         echo "$cksum" |md5sum -c --quiet || error "file differs"
16958
16959         rm -rf $DIR/$tfile
16960 }
16961 run_test 207b "can refresh layout at open"
16962
16963 test_208() {
16964         # FIXME: in this test suite, only RD lease is used. This is okay
16965         # for now as only exclusive open is supported. After generic lease
16966         # is done, this test suite should be revised. - Jinshan
16967
16968         remote_mds_nodsh && skip "remote MDS with nodsh"
16969         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16970                 skip "Need MDS version at least 2.4.52"
16971
16972         echo "==== test 1: verify get lease work"
16973         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16974
16975         echo "==== test 2: verify lease can be broken by upcoming open"
16976         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16977         local PID=$!
16978         sleep 1
16979
16980         $MULTIOP $DIR/$tfile oO_RDONLY:c
16981         kill -USR1 $PID && wait $PID || error "break lease error"
16982
16983         echo "==== test 3: verify lease can't be granted if an open already exists"
16984         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16985         local PID=$!
16986         sleep 1
16987
16988         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16989         kill -USR1 $PID && wait $PID || error "open file error"
16990
16991         echo "==== test 4: lease can sustain over recovery"
16992         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16993         PID=$!
16994         sleep 1
16995
16996         fail mds1
16997
16998         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16999
17000         echo "==== test 5: lease broken can't be regained by replay"
17001         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17002         PID=$!
17003         sleep 1
17004
17005         # open file to break lease and then recovery
17006         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17007         fail mds1
17008
17009         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17010
17011         rm -f $DIR/$tfile
17012 }
17013 run_test 208 "Exclusive open"
17014
17015 test_209() {
17016         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17017                 skip_env "must have disp_stripe"
17018
17019         touch $DIR/$tfile
17020         sync; sleep 5; sync;
17021
17022         echo 3 > /proc/sys/vm/drop_caches
17023         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17024                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17025         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17026
17027         # open/close 500 times
17028         for i in $(seq 500); do
17029                 cat $DIR/$tfile
17030         done
17031
17032         echo 3 > /proc/sys/vm/drop_caches
17033         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17034                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17035         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17036
17037         echo "before: $req_before, after: $req_after"
17038         [ $((req_after - req_before)) -ge 300 ] &&
17039                 error "open/close requests are not freed"
17040         return 0
17041 }
17042 run_test 209 "read-only open/close requests should be freed promptly"
17043
17044 test_210() {
17045         local pid
17046
17047         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17048         pid=$!
17049         sleep 1
17050
17051         $LFS getstripe $DIR/$tfile
17052         kill -USR1 $pid
17053         wait $pid || error "multiop failed"
17054
17055         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17056         pid=$!
17057         sleep 1
17058
17059         $LFS getstripe $DIR/$tfile
17060         kill -USR1 $pid
17061         wait $pid || error "multiop failed"
17062 }
17063 run_test 210 "lfs getstripe does not break leases"
17064
17065 test_212() {
17066         size=`date +%s`
17067         size=$((size % 8192 + 1))
17068         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17069         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17070         rm -f $DIR/f212 $DIR/f212.xyz
17071 }
17072 run_test 212 "Sendfile test ============================================"
17073
17074 test_213() {
17075         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17076         cancel_lru_locks osc
17077         lctl set_param fail_loc=0x8000040f
17078         # generate a read lock
17079         cat $DIR/$tfile > /dev/null
17080         # write to the file, it will try to cancel the above read lock.
17081         cat /etc/hosts >> $DIR/$tfile
17082 }
17083 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17084
17085 test_214() { # for bug 20133
17086         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17087         for (( i=0; i < 340; i++ )) ; do
17088                 touch $DIR/$tdir/d214c/a$i
17089         done
17090
17091         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17092         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17093         ls $DIR/d214c || error "ls $DIR/d214c failed"
17094         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17095         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17096 }
17097 run_test 214 "hash-indexed directory test - bug 20133"
17098
17099 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17100 create_lnet_proc_files() {
17101         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17102 }
17103
17104 # counterpart of create_lnet_proc_files
17105 remove_lnet_proc_files() {
17106         rm -f $TMP/lnet_$1.sys
17107 }
17108
17109 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17110 # 3rd arg as regexp for body
17111 check_lnet_proc_stats() {
17112         local l=$(cat "$TMP/lnet_$1" |wc -l)
17113         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17114
17115         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17116 }
17117
17118 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17119 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17120 # optional and can be regexp for 2nd line (lnet.routes case)
17121 check_lnet_proc_entry() {
17122         local blp=2          # blp stands for 'position of 1st line of body'
17123         [ -z "$5" ] || blp=3 # lnet.routes case
17124
17125         local l=$(cat "$TMP/lnet_$1" |wc -l)
17126         # subtracting one from $blp because the body can be empty
17127         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17128
17129         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17130                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17131
17132         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17133                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17134
17135         # bail out if any unexpected line happened
17136         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17137         [ "$?" != 0 ] || error "$2 misformatted"
17138 }
17139
17140 test_215() { # for bugs 18102, 21079, 21517
17141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17142
17143         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17144         local P='[1-9][0-9]*'           # positive numeric
17145         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17146         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17147         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17148         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17149
17150         local L1 # regexp for 1st line
17151         local L2 # regexp for 2nd line (optional)
17152         local BR # regexp for the rest (body)
17153
17154         # lnet.stats should look as 11 space-separated non-negative numerics
17155         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17156         create_lnet_proc_files "stats"
17157         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17158         remove_lnet_proc_files "stats"
17159
17160         # lnet.routes should look like this:
17161         # Routing disabled/enabled
17162         # net hops priority state router
17163         # where net is a string like tcp0, hops > 0, priority >= 0,
17164         # state is up/down,
17165         # router is a string like 192.168.1.1@tcp2
17166         L1="^Routing (disabled|enabled)$"
17167         L2="^net +hops +priority +state +router$"
17168         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17169         create_lnet_proc_files "routes"
17170         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17171         remove_lnet_proc_files "routes"
17172
17173         # lnet.routers should look like this:
17174         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17175         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17176         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17177         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17178         L1="^ref +rtr_ref +alive +router$"
17179         BR="^$P +$P +(up|down) +$NID$"
17180         create_lnet_proc_files "routers"
17181         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17182         remove_lnet_proc_files "routers"
17183
17184         # lnet.peers should look like this:
17185         # nid refs state last max rtr min tx min queue
17186         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17187         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17188         # numeric (0 or >0 or <0), queue >= 0.
17189         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17190         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17191         create_lnet_proc_files "peers"
17192         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17193         remove_lnet_proc_files "peers"
17194
17195         # lnet.buffers  should look like this:
17196         # pages count credits min
17197         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17198         L1="^pages +count +credits +min$"
17199         BR="^ +$N +$N +$I +$I$"
17200         create_lnet_proc_files "buffers"
17201         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17202         remove_lnet_proc_files "buffers"
17203
17204         # lnet.nis should look like this:
17205         # nid status alive refs peer rtr max tx min
17206         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17207         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17208         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17209         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17210         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17211         create_lnet_proc_files "nis"
17212         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17213         remove_lnet_proc_files "nis"
17214
17215         # can we successfully write to lnet.stats?
17216         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17217 }
17218 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17219
17220 test_216() { # bug 20317
17221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17222         remote_ost_nodsh && skip "remote OST with nodsh"
17223
17224         local node
17225         local facets=$(get_facets OST)
17226         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17227
17228         save_lustre_params client "osc.*.contention_seconds" > $p
17229         save_lustre_params $facets \
17230                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17231         save_lustre_params $facets \
17232                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17233         save_lustre_params $facets \
17234                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17235         clear_stats osc.*.osc_stats
17236
17237         # agressive lockless i/o settings
17238         do_nodes $(comma_list $(osts_nodes)) \
17239                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17240                         ldlm.namespaces.filter-*.contended_locks=0 \
17241                         ldlm.namespaces.filter-*.contention_seconds=60"
17242         lctl set_param -n osc.*.contention_seconds=60
17243
17244         $DIRECTIO write $DIR/$tfile 0 10 4096
17245         $CHECKSTAT -s 40960 $DIR/$tfile
17246
17247         # disable lockless i/o
17248         do_nodes $(comma_list $(osts_nodes)) \
17249                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17250                         ldlm.namespaces.filter-*.contended_locks=32 \
17251                         ldlm.namespaces.filter-*.contention_seconds=0"
17252         lctl set_param -n osc.*.contention_seconds=0
17253         clear_stats osc.*.osc_stats
17254
17255         dd if=/dev/zero of=$DIR/$tfile count=0
17256         $CHECKSTAT -s 0 $DIR/$tfile
17257
17258         restore_lustre_params <$p
17259         rm -f $p
17260         rm $DIR/$tfile
17261 }
17262 run_test 216 "check lockless direct write updates file size and kms correctly"
17263
17264 test_217() { # bug 22430
17265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17266
17267         local node
17268         local nid
17269
17270         for node in $(nodes_list); do
17271                 nid=$(host_nids_address $node $NETTYPE)
17272                 if [[ $nid = *-* ]] ; then
17273                         echo "lctl ping $(h2nettype $nid)"
17274                         lctl ping $(h2nettype $nid)
17275                 else
17276                         echo "skipping $node (no hyphen detected)"
17277                 fi
17278         done
17279 }
17280 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17281
17282 test_218() {
17283        # do directio so as not to populate the page cache
17284        log "creating a 10 Mb file"
17285        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17286        log "starting reads"
17287        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17288        log "truncating the file"
17289        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17290        log "killing dd"
17291        kill %+ || true # reads might have finished
17292        echo "wait until dd is finished"
17293        wait
17294        log "removing the temporary file"
17295        rm -rf $DIR/$tfile || error "tmp file removal failed"
17296 }
17297 run_test 218 "parallel read and truncate should not deadlock"
17298
17299 test_219() {
17300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17301
17302         # write one partial page
17303         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17304         # set no grant so vvp_io_commit_write will do sync write
17305         $LCTL set_param fail_loc=0x411
17306         # write a full page at the end of file
17307         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17308
17309         $LCTL set_param fail_loc=0
17310         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17311         $LCTL set_param fail_loc=0x411
17312         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17313
17314         # LU-4201
17315         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17316         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17317 }
17318 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17319
17320 test_220() { #LU-325
17321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17322         remote_ost_nodsh && skip "remote OST with nodsh"
17323         remote_mds_nodsh && skip "remote MDS with nodsh"
17324         remote_mgs_nodsh && skip "remote MGS with nodsh"
17325
17326         local OSTIDX=0
17327
17328         # create on MDT0000 so the last_id and next_id are correct
17329         mkdir $DIR/$tdir
17330         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17331         OST=${OST%_UUID}
17332
17333         # on the mdt's osc
17334         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17335         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17336                         osp.$mdtosc_proc1.prealloc_last_id)
17337         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17338                         osp.$mdtosc_proc1.prealloc_next_id)
17339
17340         $LFS df -i
17341
17342         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17343         #define OBD_FAIL_OST_ENOINO              0x229
17344         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17345         create_pool $FSNAME.$TESTNAME || return 1
17346         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17347
17348         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17349
17350         MDSOBJS=$((last_id - next_id))
17351         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17352
17353         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17354         echo "OST still has $count kbytes free"
17355
17356         echo "create $MDSOBJS files @next_id..."
17357         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17358
17359         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17360                         osp.$mdtosc_proc1.prealloc_last_id)
17361         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17362                         osp.$mdtosc_proc1.prealloc_next_id)
17363
17364         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17365         $LFS df -i
17366
17367         echo "cleanup..."
17368
17369         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17370         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17371
17372         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17373                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17374         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17375                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17376         echo "unlink $MDSOBJS files @$next_id..."
17377         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17378 }
17379 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17380
17381 test_221() {
17382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17383
17384         dd if=`which date` of=$MOUNT/date oflag=sync
17385         chmod +x $MOUNT/date
17386
17387         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17388         $LCTL set_param fail_loc=0x80001401
17389
17390         $MOUNT/date > /dev/null
17391         rm -f $MOUNT/date
17392 }
17393 run_test 221 "make sure fault and truncate race to not cause OOM"
17394
17395 test_222a () {
17396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17397
17398         rm -rf $DIR/$tdir
17399         test_mkdir $DIR/$tdir
17400         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17401         createmany -o $DIR/$tdir/$tfile 10
17402         cancel_lru_locks mdc
17403         cancel_lru_locks osc
17404         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17405         $LCTL set_param fail_loc=0x31a
17406         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17407         $LCTL set_param fail_loc=0
17408         rm -r $DIR/$tdir
17409 }
17410 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17411
17412 test_222b () {
17413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17414
17415         rm -rf $DIR/$tdir
17416         test_mkdir $DIR/$tdir
17417         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17418         createmany -o $DIR/$tdir/$tfile 10
17419         cancel_lru_locks mdc
17420         cancel_lru_locks osc
17421         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17422         $LCTL set_param fail_loc=0x31a
17423         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17424         $LCTL set_param fail_loc=0
17425 }
17426 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17427
17428 test_223 () {
17429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17430
17431         rm -rf $DIR/$tdir
17432         test_mkdir $DIR/$tdir
17433         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17434         createmany -o $DIR/$tdir/$tfile 10
17435         cancel_lru_locks mdc
17436         cancel_lru_locks osc
17437         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17438         $LCTL set_param fail_loc=0x31b
17439         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17440         $LCTL set_param fail_loc=0
17441         rm -r $DIR/$tdir
17442 }
17443 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17444
17445 test_224a() { # LU-1039, MRP-303
17446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17447
17448         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17449         $LCTL set_param fail_loc=0x508
17450         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17451         $LCTL set_param fail_loc=0
17452         df $DIR
17453 }
17454 run_test 224a "Don't panic on bulk IO failure"
17455
17456 test_224b() { # LU-1039, MRP-303
17457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17458
17459         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17460         cancel_lru_locks osc
17461         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17462         $LCTL set_param fail_loc=0x515
17463         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17464         $LCTL set_param fail_loc=0
17465         df $DIR
17466 }
17467 run_test 224b "Don't panic on bulk IO failure"
17468
17469 test_224c() { # LU-6441
17470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17471         remote_mds_nodsh && skip "remote MDS with nodsh"
17472
17473         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17474         save_writethrough $p
17475         set_cache writethrough on
17476
17477         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17478         local at_max=$($LCTL get_param -n at_max)
17479         local timeout=$($LCTL get_param -n timeout)
17480         local test_at="at_max"
17481         local param_at="$FSNAME.sys.at_max"
17482         local test_timeout="timeout"
17483         local param_timeout="$FSNAME.sys.timeout"
17484
17485         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17486
17487         set_persistent_param_and_check client "$test_at" "$param_at" 0
17488         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17489
17490         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17491         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17492         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17493         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17494         sync
17495         do_facet ost1 "$LCTL set_param fail_loc=0"
17496
17497         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17498         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17499                 $timeout
17500
17501         $LCTL set_param -n $pages_per_rpc
17502         restore_lustre_params < $p
17503         rm -f $p
17504 }
17505 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17506
17507 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17508 test_225a () {
17509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17510         if [ -z ${MDSSURVEY} ]; then
17511                 skip_env "mds-survey not found"
17512         fi
17513         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17514                 skip "Need MDS version at least 2.2.51"
17515
17516         local mds=$(facet_host $SINGLEMDS)
17517         local target=$(do_nodes $mds 'lctl dl' |
17518                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17519
17520         local cmd1="file_count=1000 thrhi=4"
17521         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17522         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17523         local cmd="$cmd1 $cmd2 $cmd3"
17524
17525         rm -f ${TMP}/mds_survey*
17526         echo + $cmd
17527         eval $cmd || error "mds-survey with zero-stripe failed"
17528         cat ${TMP}/mds_survey*
17529         rm -f ${TMP}/mds_survey*
17530 }
17531 run_test 225a "Metadata survey sanity with zero-stripe"
17532
17533 test_225b () {
17534         if [ -z ${MDSSURVEY} ]; then
17535                 skip_env "mds-survey not found"
17536         fi
17537         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17538                 skip "Need MDS version at least 2.2.51"
17539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17540         remote_mds_nodsh && skip "remote MDS with nodsh"
17541         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17542                 skip_env "Need to mount OST to test"
17543         fi
17544
17545         local mds=$(facet_host $SINGLEMDS)
17546         local target=$(do_nodes $mds 'lctl dl' |
17547                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17548
17549         local cmd1="file_count=1000 thrhi=4"
17550         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17551         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17552         local cmd="$cmd1 $cmd2 $cmd3"
17553
17554         rm -f ${TMP}/mds_survey*
17555         echo + $cmd
17556         eval $cmd || error "mds-survey with stripe_count failed"
17557         cat ${TMP}/mds_survey*
17558         rm -f ${TMP}/mds_survey*
17559 }
17560 run_test 225b "Metadata survey sanity with stripe_count = 1"
17561
17562 mcreate_path2fid () {
17563         local mode=$1
17564         local major=$2
17565         local minor=$3
17566         local name=$4
17567         local desc=$5
17568         local path=$DIR/$tdir/$name
17569         local fid
17570         local rc
17571         local fid_path
17572
17573         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17574                 error "cannot create $desc"
17575
17576         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17577         rc=$?
17578         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17579
17580         fid_path=$($LFS fid2path $MOUNT $fid)
17581         rc=$?
17582         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17583
17584         [ "$path" == "$fid_path" ] ||
17585                 error "fid2path returned $fid_path, expected $path"
17586
17587         echo "pass with $path and $fid"
17588 }
17589
17590 test_226a () {
17591         rm -rf $DIR/$tdir
17592         mkdir -p $DIR/$tdir
17593
17594         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17595         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17596         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17597         mcreate_path2fid 0040666 0 0 dir "directory"
17598         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17599         mcreate_path2fid 0100666 0 0 file "regular file"
17600         mcreate_path2fid 0120666 0 0 link "symbolic link"
17601         mcreate_path2fid 0140666 0 0 sock "socket"
17602 }
17603 run_test 226a "call path2fid and fid2path on files of all type"
17604
17605 test_226b () {
17606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17607
17608         local MDTIDX=1
17609
17610         rm -rf $DIR/$tdir
17611         mkdir -p $DIR/$tdir
17612         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17613                 error "create remote directory failed"
17614         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17615         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17616                                 "character special file (null)"
17617         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17618                                 "character special file (no device)"
17619         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17620         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17621                                 "block special file (loop)"
17622         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17623         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17624         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17625 }
17626 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17627
17628 test_226c () {
17629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17630         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17631                 skip "Need MDS version at least 2.13.55"
17632
17633         local submnt=/mnt/submnt
17634         local srcfile=/etc/passwd
17635         local dstfile=$submnt/passwd
17636         local path
17637         local fid
17638
17639         rm -rf $DIR/$tdir
17640         rm -rf $submnt
17641         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17642                 error "create remote directory failed"
17643         mkdir -p $submnt || error "create $submnt failed"
17644         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17645                 error "mount $submnt failed"
17646         stack_trap "umount $submnt" EXIT
17647
17648         cp $srcfile $dstfile
17649         fid=$($LFS path2fid $dstfile)
17650         path=$($LFS fid2path $submnt "$fid")
17651         [ "$path" = "$dstfile" ] ||
17652                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17653 }
17654 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17655
17656 # LU-1299 Executing or running ldd on a truncated executable does not
17657 # cause an out-of-memory condition.
17658 test_227() {
17659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17660         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17661
17662         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17663         chmod +x $MOUNT/date
17664
17665         $MOUNT/date > /dev/null
17666         ldd $MOUNT/date > /dev/null
17667         rm -f $MOUNT/date
17668 }
17669 run_test 227 "running truncated executable does not cause OOM"
17670
17671 # LU-1512 try to reuse idle OI blocks
17672 test_228a() {
17673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17674         remote_mds_nodsh && skip "remote MDS with nodsh"
17675         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17676
17677         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17678         local myDIR=$DIR/$tdir
17679
17680         mkdir -p $myDIR
17681         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17682         $LCTL set_param fail_loc=0x80001002
17683         createmany -o $myDIR/t- 10000
17684         $LCTL set_param fail_loc=0
17685         # The guard is current the largest FID holder
17686         touch $myDIR/guard
17687         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17688                     tr -d '[')
17689         local IDX=$(($SEQ % 64))
17690
17691         do_facet $SINGLEMDS sync
17692         # Make sure journal flushed.
17693         sleep 6
17694         local blk1=$(do_facet $SINGLEMDS \
17695                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17696                      grep Blockcount | awk '{print $4}')
17697
17698         # Remove old files, some OI blocks will become idle.
17699         unlinkmany $myDIR/t- 10000
17700         # Create new files, idle OI blocks should be reused.
17701         createmany -o $myDIR/t- 2000
17702         do_facet $SINGLEMDS sync
17703         # Make sure journal flushed.
17704         sleep 6
17705         local blk2=$(do_facet $SINGLEMDS \
17706                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17707                      grep Blockcount | awk '{print $4}')
17708
17709         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17710 }
17711 run_test 228a "try to reuse idle OI blocks"
17712
17713 test_228b() {
17714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17715         remote_mds_nodsh && skip "remote MDS with nodsh"
17716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17717
17718         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17719         local myDIR=$DIR/$tdir
17720
17721         mkdir -p $myDIR
17722         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17723         $LCTL set_param fail_loc=0x80001002
17724         createmany -o $myDIR/t- 10000
17725         $LCTL set_param fail_loc=0
17726         # The guard is current the largest FID holder
17727         touch $myDIR/guard
17728         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17729                     tr -d '[')
17730         local IDX=$(($SEQ % 64))
17731
17732         do_facet $SINGLEMDS sync
17733         # Make sure journal flushed.
17734         sleep 6
17735         local blk1=$(do_facet $SINGLEMDS \
17736                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17737                      grep Blockcount | awk '{print $4}')
17738
17739         # Remove old files, some OI blocks will become idle.
17740         unlinkmany $myDIR/t- 10000
17741
17742         # stop the MDT
17743         stop $SINGLEMDS || error "Fail to stop MDT."
17744         # remount the MDT
17745         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17746
17747         df $MOUNT || error "Fail to df."
17748         # Create new files, idle OI blocks should be reused.
17749         createmany -o $myDIR/t- 2000
17750         do_facet $SINGLEMDS sync
17751         # Make sure journal flushed.
17752         sleep 6
17753         local blk2=$(do_facet $SINGLEMDS \
17754                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17755                      grep Blockcount | awk '{print $4}')
17756
17757         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17758 }
17759 run_test 228b "idle OI blocks can be reused after MDT restart"
17760
17761 #LU-1881
17762 test_228c() {
17763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17764         remote_mds_nodsh && skip "remote MDS with nodsh"
17765         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17766
17767         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17768         local myDIR=$DIR/$tdir
17769
17770         mkdir -p $myDIR
17771         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17772         $LCTL set_param fail_loc=0x80001002
17773         # 20000 files can guarantee there are index nodes in the OI file
17774         createmany -o $myDIR/t- 20000
17775         $LCTL set_param fail_loc=0
17776         # The guard is current the largest FID holder
17777         touch $myDIR/guard
17778         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17779                     tr -d '[')
17780         local IDX=$(($SEQ % 64))
17781
17782         do_facet $SINGLEMDS sync
17783         # Make sure journal flushed.
17784         sleep 6
17785         local blk1=$(do_facet $SINGLEMDS \
17786                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17787                      grep Blockcount | awk '{print $4}')
17788
17789         # Remove old files, some OI blocks will become idle.
17790         unlinkmany $myDIR/t- 20000
17791         rm -f $myDIR/guard
17792         # The OI file should become empty now
17793
17794         # Create new files, idle OI blocks should be reused.
17795         createmany -o $myDIR/t- 2000
17796         do_facet $SINGLEMDS sync
17797         # Make sure journal flushed.
17798         sleep 6
17799         local blk2=$(do_facet $SINGLEMDS \
17800                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17801                      grep Blockcount | awk '{print $4}')
17802
17803         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17804 }
17805 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17806
17807 test_229() { # LU-2482, LU-3448
17808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17809         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17810         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17811                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17812
17813         rm -f $DIR/$tfile
17814
17815         # Create a file with a released layout and stripe count 2.
17816         $MULTIOP $DIR/$tfile H2c ||
17817                 error "failed to create file with released layout"
17818
17819         $LFS getstripe -v $DIR/$tfile
17820
17821         local pattern=$($LFS getstripe -L $DIR/$tfile)
17822         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17823
17824         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17825                 error "getstripe"
17826         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17827         stat $DIR/$tfile || error "failed to stat released file"
17828
17829         chown $RUNAS_ID $DIR/$tfile ||
17830                 error "chown $RUNAS_ID $DIR/$tfile failed"
17831
17832         chgrp $RUNAS_ID $DIR/$tfile ||
17833                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17834
17835         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17836         rm $DIR/$tfile || error "failed to remove released file"
17837 }
17838 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17839
17840 test_230a() {
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17843         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17844                 skip "Need MDS version at least 2.11.52"
17845
17846         local MDTIDX=1
17847
17848         test_mkdir $DIR/$tdir
17849         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17850         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17851         [ $mdt_idx -ne 0 ] &&
17852                 error "create local directory on wrong MDT $mdt_idx"
17853
17854         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17855                         error "create remote directory failed"
17856         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17857         [ $mdt_idx -ne $MDTIDX ] &&
17858                 error "create remote directory on wrong MDT $mdt_idx"
17859
17860         createmany -o $DIR/$tdir/test_230/t- 10 ||
17861                 error "create files on remote directory failed"
17862         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17863         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17864         rm -r $DIR/$tdir || error "unlink remote directory failed"
17865 }
17866 run_test 230a "Create remote directory and files under the remote directory"
17867
17868 test_230b() {
17869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17871         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17872                 skip "Need MDS version at least 2.11.52"
17873
17874         local MDTIDX=1
17875         local mdt_index
17876         local i
17877         local file
17878         local pid
17879         local stripe_count
17880         local migrate_dir=$DIR/$tdir/migrate_dir
17881         local other_dir=$DIR/$tdir/other_dir
17882
17883         test_mkdir $DIR/$tdir
17884         test_mkdir -i0 -c1 $migrate_dir
17885         test_mkdir -i0 -c1 $other_dir
17886         for ((i=0; i<10; i++)); do
17887                 mkdir -p $migrate_dir/dir_${i}
17888                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17889                         error "create files under remote dir failed $i"
17890         done
17891
17892         cp /etc/passwd $migrate_dir/$tfile
17893         cp /etc/passwd $other_dir/$tfile
17894         chattr +SAD $migrate_dir
17895         chattr +SAD $migrate_dir/$tfile
17896
17897         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17898         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17899         local old_dir_mode=$(stat -c%f $migrate_dir)
17900         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17901
17902         mkdir -p $migrate_dir/dir_default_stripe2
17903         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17904         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17905
17906         mkdir -p $other_dir
17907         ln $migrate_dir/$tfile $other_dir/luna
17908         ln $migrate_dir/$tfile $migrate_dir/sofia
17909         ln $other_dir/$tfile $migrate_dir/david
17910         ln -s $migrate_dir/$tfile $other_dir/zachary
17911         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17912         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17913
17914         local len
17915         local lnktgt
17916
17917         # inline symlink
17918         for len in 58 59 60; do
17919                 lnktgt=$(str_repeat 'l' $len)
17920                 touch $migrate_dir/$lnktgt
17921                 ln -s $lnktgt $migrate_dir/${len}char_ln
17922         done
17923
17924         # PATH_MAX
17925         for len in 4094 4095; do
17926                 lnktgt=$(str_repeat 'l' $len)
17927                 ln -s $lnktgt $migrate_dir/${len}char_ln
17928         done
17929
17930         # NAME_MAX
17931         for len in 254 255; do
17932                 touch $migrate_dir/$(str_repeat 'l' $len)
17933         done
17934
17935         $LFS migrate -m $MDTIDX $migrate_dir ||
17936                 error "fails on migrating remote dir to MDT1"
17937
17938         echo "migratate to MDT1, then checking.."
17939         for ((i = 0; i < 10; i++)); do
17940                 for file in $(find $migrate_dir/dir_${i}); do
17941                         mdt_index=$($LFS getstripe -m $file)
17942                         # broken symlink getstripe will fail
17943                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17944                                 error "$file is not on MDT${MDTIDX}"
17945                 done
17946         done
17947
17948         # the multiple link file should still in MDT0
17949         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17950         [ $mdt_index == 0 ] ||
17951                 error "$file is not on MDT${MDTIDX}"
17952
17953         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17954         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17955                 error " expect $old_dir_flag get $new_dir_flag"
17956
17957         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17958         [ "$old_file_flag" = "$new_file_flag" ] ||
17959                 error " expect $old_file_flag get $new_file_flag"
17960
17961         local new_dir_mode=$(stat -c%f $migrate_dir)
17962         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17963                 error "expect mode $old_dir_mode get $new_dir_mode"
17964
17965         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17966         [ "$old_file_mode" = "$new_file_mode" ] ||
17967                 error "expect mode $old_file_mode get $new_file_mode"
17968
17969         diff /etc/passwd $migrate_dir/$tfile ||
17970                 error "$tfile different after migration"
17971
17972         diff /etc/passwd $other_dir/luna ||
17973                 error "luna different after migration"
17974
17975         diff /etc/passwd $migrate_dir/sofia ||
17976                 error "sofia different after migration"
17977
17978         diff /etc/passwd $migrate_dir/david ||
17979                 error "david different after migration"
17980
17981         diff /etc/passwd $other_dir/zachary ||
17982                 error "zachary different after migration"
17983
17984         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17985                 error "${tfile}_ln different after migration"
17986
17987         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17988                 error "${tfile}_ln_other different after migration"
17989
17990         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17991         [ $stripe_count = 2 ] ||
17992                 error "dir strpe_count $d != 2 after migration."
17993
17994         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17995         [ $stripe_count = 2 ] ||
17996                 error "file strpe_count $d != 2 after migration."
17997
17998         #migrate back to MDT0
17999         MDTIDX=0
18000
18001         $LFS migrate -m $MDTIDX $migrate_dir ||
18002                 error "fails on migrating remote dir to MDT0"
18003
18004         echo "migrate back to MDT0, checking.."
18005         for file in $(find $migrate_dir); do
18006                 mdt_index=$($LFS getstripe -m $file)
18007                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18008                         error "$file is not on MDT${MDTIDX}"
18009         done
18010
18011         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18012         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18013                 error " expect $old_dir_flag get $new_dir_flag"
18014
18015         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18016         [ "$old_file_flag" = "$new_file_flag" ] ||
18017                 error " expect $old_file_flag get $new_file_flag"
18018
18019         local new_dir_mode=$(stat -c%f $migrate_dir)
18020         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18021                 error "expect mode $old_dir_mode get $new_dir_mode"
18022
18023         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18024         [ "$old_file_mode" = "$new_file_mode" ] ||
18025                 error "expect mode $old_file_mode get $new_file_mode"
18026
18027         diff /etc/passwd ${migrate_dir}/$tfile ||
18028                 error "$tfile different after migration"
18029
18030         diff /etc/passwd ${other_dir}/luna ||
18031                 error "luna different after migration"
18032
18033         diff /etc/passwd ${migrate_dir}/sofia ||
18034                 error "sofia different after migration"
18035
18036         diff /etc/passwd ${other_dir}/zachary ||
18037                 error "zachary different after migration"
18038
18039         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18040                 error "${tfile}_ln different after migration"
18041
18042         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18043                 error "${tfile}_ln_other different after migration"
18044
18045         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18046         [ $stripe_count = 2 ] ||
18047                 error "dir strpe_count $d != 2 after migration."
18048
18049         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18050         [ $stripe_count = 2 ] ||
18051                 error "file strpe_count $d != 2 after migration."
18052
18053         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18054 }
18055 run_test 230b "migrate directory"
18056
18057 test_230c() {
18058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18060         remote_mds_nodsh && skip "remote MDS with nodsh"
18061         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18062                 skip "Need MDS version at least 2.11.52"
18063
18064         local MDTIDX=1
18065         local total=3
18066         local mdt_index
18067         local file
18068         local migrate_dir=$DIR/$tdir/migrate_dir
18069
18070         #If migrating directory fails in the middle, all entries of
18071         #the directory is still accessiable.
18072         test_mkdir $DIR/$tdir
18073         test_mkdir -i0 -c1 $migrate_dir
18074         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18075         stat $migrate_dir
18076         createmany -o $migrate_dir/f $total ||
18077                 error "create files under ${migrate_dir} failed"
18078
18079         # fail after migrating top dir, and this will fail only once, so the
18080         # first sub file migration will fail (currently f3), others succeed.
18081         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18082         do_facet mds1 lctl set_param fail_loc=0x1801
18083         local t=$(ls $migrate_dir | wc -l)
18084         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18085                 error "migrate should fail"
18086         local u=$(ls $migrate_dir | wc -l)
18087         [ "$u" == "$t" ] || error "$u != $t during migration"
18088
18089         # add new dir/file should succeed
18090         mkdir $migrate_dir/dir ||
18091                 error "mkdir failed under migrating directory"
18092         touch $migrate_dir/file ||
18093                 error "create file failed under migrating directory"
18094
18095         # add file with existing name should fail
18096         for file in $migrate_dir/f*; do
18097                 stat $file > /dev/null || error "stat $file failed"
18098                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18099                         error "open(O_CREAT|O_EXCL) $file should fail"
18100                 $MULTIOP $file m && error "create $file should fail"
18101                 touch $DIR/$tdir/remote_dir/$tfile ||
18102                         error "touch $tfile failed"
18103                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18104                         error "link $file should fail"
18105                 mdt_index=$($LFS getstripe -m $file)
18106                 if [ $mdt_index == 0 ]; then
18107                         # file failed to migrate is not allowed to rename to
18108                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18109                                 error "rename to $file should fail"
18110                 else
18111                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18112                                 error "rename to $file failed"
18113                 fi
18114                 echo hello >> $file || error "write $file failed"
18115         done
18116
18117         # resume migration with different options should fail
18118         $LFS migrate -m 0 $migrate_dir &&
18119                 error "migrate -m 0 $migrate_dir should fail"
18120
18121         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18122                 error "migrate -c 2 $migrate_dir should fail"
18123
18124         # resume migration should succeed
18125         $LFS migrate -m $MDTIDX $migrate_dir ||
18126                 error "migrate $migrate_dir failed"
18127
18128         echo "Finish migration, then checking.."
18129         for file in $(find $migrate_dir); do
18130                 mdt_index=$($LFS getstripe -m $file)
18131                 [ $mdt_index == $MDTIDX ] ||
18132                         error "$file is not on MDT${MDTIDX}"
18133         done
18134
18135         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18136 }
18137 run_test 230c "check directory accessiblity if migration failed"
18138
18139 test_230d() {
18140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18142         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18143                 skip "Need MDS version at least 2.11.52"
18144         # LU-11235
18145         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18146
18147         local migrate_dir=$DIR/$tdir/migrate_dir
18148         local old_index
18149         local new_index
18150         local old_count
18151         local new_count
18152         local new_hash
18153         local mdt_index
18154         local i
18155         local j
18156
18157         old_index=$((RANDOM % MDSCOUNT))
18158         old_count=$((MDSCOUNT - old_index))
18159         new_index=$((RANDOM % MDSCOUNT))
18160         new_count=$((MDSCOUNT - new_index))
18161         new_hash=1 # for all_char
18162
18163         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18164         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18165
18166         test_mkdir $DIR/$tdir
18167         test_mkdir -i $old_index -c $old_count $migrate_dir
18168
18169         for ((i=0; i<100; i++)); do
18170                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18171                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18172                         error "create files under remote dir failed $i"
18173         done
18174
18175         echo -n "Migrate from MDT$old_index "
18176         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18177         echo -n "to MDT$new_index"
18178         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18179         echo
18180
18181         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18182         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18183                 error "migrate remote dir error"
18184
18185         echo "Finish migration, then checking.."
18186         for file in $(find $migrate_dir); do
18187                 mdt_index=$($LFS getstripe -m $file)
18188                 if [ $mdt_index -lt $new_index ] ||
18189                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18190                         error "$file is on MDT$mdt_index"
18191                 fi
18192         done
18193
18194         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18195 }
18196 run_test 230d "check migrate big directory"
18197
18198 test_230e() {
18199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18201         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18202                 skip "Need MDS version at least 2.11.52"
18203
18204         local i
18205         local j
18206         local a_fid
18207         local b_fid
18208
18209         mkdir -p $DIR/$tdir
18210         mkdir $DIR/$tdir/migrate_dir
18211         mkdir $DIR/$tdir/other_dir
18212         touch $DIR/$tdir/migrate_dir/a
18213         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18214         ls $DIR/$tdir/other_dir
18215
18216         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18217                 error "migrate dir fails"
18218
18219         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18220         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18221
18222         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18223         [ $mdt_index == 0 ] || error "a is not on MDT0"
18224
18225         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18226                 error "migrate dir fails"
18227
18228         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18229         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18230
18231         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18232         [ $mdt_index == 1 ] || error "a is not on MDT1"
18233
18234         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18235         [ $mdt_index == 1 ] || error "b is not on MDT1"
18236
18237         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18238         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18239
18240         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18241
18242         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18243 }
18244 run_test 230e "migrate mulitple local link files"
18245
18246 test_230f() {
18247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18250                 skip "Need MDS version at least 2.11.52"
18251
18252         local a_fid
18253         local ln_fid
18254
18255         mkdir -p $DIR/$tdir
18256         mkdir $DIR/$tdir/migrate_dir
18257         $LFS mkdir -i1 $DIR/$tdir/other_dir
18258         touch $DIR/$tdir/migrate_dir/a
18259         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18260         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18261         ls $DIR/$tdir/other_dir
18262
18263         # a should be migrated to MDT1, since no other links on MDT0
18264         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18265                 error "#1 migrate dir fails"
18266         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18267         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18268         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18269         [ $mdt_index == 1 ] || error "a is not on MDT1"
18270
18271         # a should stay on MDT1, because it is a mulitple link file
18272         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18273                 error "#2 migrate dir fails"
18274         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18275         [ $mdt_index == 1 ] || error "a is not on MDT1"
18276
18277         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18278                 error "#3 migrate dir fails"
18279
18280         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18281         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18282         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18283
18284         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18285         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18286
18287         # a should be migrated to MDT0, since no other links on MDT1
18288         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18289                 error "#4 migrate dir fails"
18290         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18291         [ $mdt_index == 0 ] || error "a is not on MDT0"
18292
18293         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18294 }
18295 run_test 230f "migrate mulitple remote link files"
18296
18297 test_230g() {
18298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18300         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18301                 skip "Need MDS version at least 2.11.52"
18302
18303         mkdir -p $DIR/$tdir/migrate_dir
18304
18305         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18306                 error "migrating dir to non-exist MDT succeeds"
18307         true
18308 }
18309 run_test 230g "migrate dir to non-exist MDT"
18310
18311 test_230h() {
18312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18313         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18314         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18315                 skip "Need MDS version at least 2.11.52"
18316
18317         local mdt_index
18318
18319         mkdir -p $DIR/$tdir/migrate_dir
18320
18321         $LFS migrate -m1 $DIR &&
18322                 error "migrating mountpoint1 should fail"
18323
18324         $LFS migrate -m1 $DIR/$tdir/.. &&
18325                 error "migrating mountpoint2 should fail"
18326
18327         # same as mv
18328         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18329                 error "migrating $tdir/migrate_dir/.. should fail"
18330
18331         true
18332 }
18333 run_test 230h "migrate .. and root"
18334
18335 test_230i() {
18336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18338         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18339                 skip "Need MDS version at least 2.11.52"
18340
18341         mkdir -p $DIR/$tdir/migrate_dir
18342
18343         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18344                 error "migration fails with a tailing slash"
18345
18346         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18347                 error "migration fails with two tailing slashes"
18348 }
18349 run_test 230i "lfs migrate -m tolerates trailing slashes"
18350
18351 test_230j() {
18352         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18353         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18354                 skip "Need MDS version at least 2.11.52"
18355
18356         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18357         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18358                 error "create $tfile failed"
18359         cat /etc/passwd > $DIR/$tdir/$tfile
18360
18361         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18362
18363         cmp /etc/passwd $DIR/$tdir/$tfile ||
18364                 error "DoM file mismatch after migration"
18365 }
18366 run_test 230j "DoM file data not changed after dir migration"
18367
18368 test_230k() {
18369         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18370         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18371                 skip "Need MDS version at least 2.11.56"
18372
18373         local total=20
18374         local files_on_starting_mdt=0
18375
18376         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18377         $LFS getdirstripe $DIR/$tdir
18378         for i in $(seq $total); do
18379                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18380                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18381                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18382         done
18383
18384         echo "$files_on_starting_mdt files on MDT0"
18385
18386         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18387         $LFS getdirstripe $DIR/$tdir
18388
18389         files_on_starting_mdt=0
18390         for i in $(seq $total); do
18391                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18392                         error "file $tfile.$i mismatch after migration"
18393                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18394                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18395         done
18396
18397         echo "$files_on_starting_mdt files on MDT1 after migration"
18398         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18399
18400         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18401         $LFS getdirstripe $DIR/$tdir
18402
18403         files_on_starting_mdt=0
18404         for i in $(seq $total); do
18405                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18406                         error "file $tfile.$i mismatch after 2nd migration"
18407                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18408                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18409         done
18410
18411         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18412         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18413
18414         true
18415 }
18416 run_test 230k "file data not changed after dir migration"
18417
18418 test_230l() {
18419         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18420         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18421                 skip "Need MDS version at least 2.11.56"
18422
18423         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18424         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18425                 error "create files under remote dir failed $i"
18426         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18427 }
18428 run_test 230l "readdir between MDTs won't crash"
18429
18430 test_230m() {
18431         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18432         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18433                 skip "Need MDS version at least 2.11.56"
18434
18435         local MDTIDX=1
18436         local mig_dir=$DIR/$tdir/migrate_dir
18437         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18438         local shortstr="b"
18439         local val
18440
18441         echo "Creating files and dirs with xattrs"
18442         test_mkdir $DIR/$tdir
18443         test_mkdir -i0 -c1 $mig_dir
18444         mkdir $mig_dir/dir
18445         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18446                 error "cannot set xattr attr1 on dir"
18447         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18448                 error "cannot set xattr attr2 on dir"
18449         touch $mig_dir/dir/f0
18450         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18451                 error "cannot set xattr attr1 on file"
18452         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18453                 error "cannot set xattr attr2 on file"
18454         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18455         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18456         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18457         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18458         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18459         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18460         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18461         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18462         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18463
18464         echo "Migrating to MDT1"
18465         $LFS migrate -m $MDTIDX $mig_dir ||
18466                 error "fails on migrating dir to MDT1"
18467
18468         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18469         echo "Checking xattrs"
18470         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18471         [ "$val" = $longstr ] ||
18472                 error "expecting xattr1 $longstr on dir, found $val"
18473         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18474         [ "$val" = $shortstr ] ||
18475                 error "expecting xattr2 $shortstr on dir, found $val"
18476         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18477         [ "$val" = $longstr ] ||
18478                 error "expecting xattr1 $longstr on file, found $val"
18479         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18480         [ "$val" = $shortstr ] ||
18481                 error "expecting xattr2 $shortstr on file, found $val"
18482 }
18483 run_test 230m "xattrs not changed after dir migration"
18484
18485 test_230n() {
18486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18487         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18488                 skip "Need MDS version at least 2.13.53"
18489
18490         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18491         cat /etc/hosts > $DIR/$tdir/$tfile
18492         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18493         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18494
18495         cmp /etc/hosts $DIR/$tdir/$tfile ||
18496                 error "File data mismatch after migration"
18497 }
18498 run_test 230n "Dir migration with mirrored file"
18499
18500 test_230o() {
18501         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18502         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18503                 skip "Need MDS version at least 2.13.52"
18504
18505         local mdts=$(comma_list $(mdts_nodes))
18506         local timeout=100
18507
18508         local restripe_status
18509         local delta
18510         local i
18511         local j
18512
18513         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18514
18515         # in case "crush" hash type is not set
18516         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18517
18518         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18519                            mdt.*MDT0000.enable_dir_restripe)
18520         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18521         stack_trap "do_nodes $mdts $LCTL set_param \
18522                     mdt.*.enable_dir_restripe=$restripe_status"
18523
18524         mkdir $DIR/$tdir
18525         createmany -m $DIR/$tdir/f 100 ||
18526                 error "create files under remote dir failed $i"
18527         createmany -d $DIR/$tdir/d 100 ||
18528                 error "create dirs under remote dir failed $i"
18529
18530         for i in $(seq 2 $MDSCOUNT); do
18531                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18532                 $LFS setdirstripe -c $i $DIR/$tdir ||
18533                         error "split -c $i $tdir failed"
18534                 wait_update $HOSTNAME \
18535                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18536                         error "dir split not finished"
18537                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18538                         awk '/migrate/ {sum += $2} END { print sum }')
18539                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18540                 # delta is around total_files/stripe_count
18541                 [ $delta -lt $((200 /(i - 1))) ] ||
18542                         error "$delta files migrated"
18543         done
18544 }
18545 run_test 230o "dir split"
18546
18547 test_230p() {
18548         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18549         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18550                 skip "Need MDS version at least 2.13.52"
18551
18552         local mdts=$(comma_list $(mdts_nodes))
18553         local timeout=100
18554
18555         local restripe_status
18556         local delta
18557         local i
18558         local j
18559
18560         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18561
18562         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18563
18564         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18565                            mdt.*MDT0000.enable_dir_restripe)
18566         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18567         stack_trap "do_nodes $mdts $LCTL set_param \
18568                     mdt.*.enable_dir_restripe=$restripe_status"
18569
18570         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18571         createmany -m $DIR/$tdir/f 100 ||
18572                 error "create files under remote dir failed $i"
18573         createmany -d $DIR/$tdir/d 100 ||
18574                 error "create dirs under remote dir failed $i"
18575
18576         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18577                 local mdt_hash="crush"
18578
18579                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18580                 $LFS setdirstripe -c $i $DIR/$tdir ||
18581                         error "split -c $i $tdir failed"
18582                 [ $i -eq 1 ] && mdt_hash="none"
18583                 wait_update $HOSTNAME \
18584                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18585                         error "dir merge not finished"
18586                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18587                         awk '/migrate/ {sum += $2} END { print sum }')
18588                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18589                 # delta is around total_files/stripe_count
18590                 [ $delta -lt $((200 / i)) ] ||
18591                         error "$delta files migrated"
18592         done
18593 }
18594 run_test 230p "dir merge"
18595
18596 test_230q() {
18597         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18598         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18599                 skip "Need MDS version at least 2.13.52"
18600
18601         local mdts=$(comma_list $(mdts_nodes))
18602         local saved_threshold=$(do_facet mds1 \
18603                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18604         local saved_delta=$(do_facet mds1 \
18605                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18606         local threshold=100
18607         local delta=2
18608         local total=0
18609         local stripe_count=0
18610         local stripe_index
18611         local nr_files
18612
18613         # test with fewer files on ZFS
18614         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18615
18616         stack_trap "do_nodes $mdts $LCTL set_param \
18617                     mdt.*.dir_split_count=$saved_threshold"
18618         stack_trap "do_nodes $mdts $LCTL set_param \
18619                     mdt.*.dir_split_delta=$saved_delta"
18620         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18621         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18622         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18623         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18624         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18625         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18626
18627         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18628         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18629
18630         while [ $stripe_count -lt $MDSCOUNT ]; do
18631                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18632                         error "create sub files failed"
18633                 stat $DIR/$tdir > /dev/null
18634                 total=$((total + threshold * 3 / 2))
18635                 stripe_count=$((stripe_count + delta))
18636                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18637
18638                 wait_update $HOSTNAME \
18639                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18640                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18641
18642                 wait_update $HOSTNAME \
18643                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18644                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18645
18646                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18647                            grep -w $stripe_index | wc -l)
18648                 echo "$nr_files files on MDT$stripe_index after split"
18649                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18650                         error "$nr_files files on MDT$stripe_index after split"
18651
18652                 nr_files=$(ls $DIR/$tdir | wc -w)
18653                 [ $nr_files -eq $total ] ||
18654                         error "total sub files $nr_files != $total"
18655         done
18656 }
18657 run_test 230q "dir auto split"
18658
18659 test_230r() {
18660         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18661         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18662         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18663                 skip "Need MDS version at least 2.13.54"
18664
18665         # maximum amount of local locks:
18666         # parent striped dir - 2 locks
18667         # new stripe in parent to migrate to - 1 lock
18668         # source and target - 2 locks
18669         # Total 5 locks for regular file
18670         mkdir -p $DIR/$tdir
18671         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18672         touch $DIR/$tdir/dir1/eee
18673
18674         # create 4 hardlink for 4 more locks
18675         # Total: 9 locks > RS_MAX_LOCKS (8)
18676         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18677         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18678         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18679         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18680         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18681         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18682         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18683         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18684
18685         cancel_lru_locks mdc
18686
18687         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18688                 error "migrate dir fails"
18689
18690         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18691 }
18692 run_test 230r "migrate with too many local locks"
18693
18694 test_231a()
18695 {
18696         # For simplicity this test assumes that max_pages_per_rpc
18697         # is the same across all OSCs
18698         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18699         local bulk_size=$((max_pages * PAGE_SIZE))
18700         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18701                                        head -n 1)
18702
18703         mkdir -p $DIR/$tdir
18704         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18705                 error "failed to set stripe with -S ${brw_size}M option"
18706
18707         # clear the OSC stats
18708         $LCTL set_param osc.*.stats=0 &>/dev/null
18709         stop_writeback
18710
18711         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18712         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18713                 oflag=direct &>/dev/null || error "dd failed"
18714
18715         sync; sleep 1; sync # just to be safe
18716         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18717         if [ x$nrpcs != "x1" ]; then
18718                 $LCTL get_param osc.*.stats
18719                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18720         fi
18721
18722         start_writeback
18723         # Drop the OSC cache, otherwise we will read from it
18724         cancel_lru_locks osc
18725
18726         # clear the OSC stats
18727         $LCTL set_param osc.*.stats=0 &>/dev/null
18728
18729         # Client reads $bulk_size.
18730         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18731                 iflag=direct &>/dev/null || error "dd failed"
18732
18733         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18734         if [ x$nrpcs != "x1" ]; then
18735                 $LCTL get_param osc.*.stats
18736                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18737         fi
18738 }
18739 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18740
18741 test_231b() {
18742         mkdir -p $DIR/$tdir
18743         local i
18744         for i in {0..1023}; do
18745                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18746                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18747                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18748         done
18749         sync
18750 }
18751 run_test 231b "must not assert on fully utilized OST request buffer"
18752
18753 test_232a() {
18754         mkdir -p $DIR/$tdir
18755         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18756
18757         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18758         do_facet ost1 $LCTL set_param fail_loc=0x31c
18759
18760         # ignore dd failure
18761         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18762
18763         do_facet ost1 $LCTL set_param fail_loc=0
18764         umount_client $MOUNT || error "umount failed"
18765         mount_client $MOUNT || error "mount failed"
18766         stop ost1 || error "cannot stop ost1"
18767         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18768 }
18769 run_test 232a "failed lock should not block umount"
18770
18771 test_232b() {
18772         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18773                 skip "Need MDS version at least 2.10.58"
18774
18775         mkdir -p $DIR/$tdir
18776         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18777         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18778         sync
18779         cancel_lru_locks osc
18780
18781         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18782         do_facet ost1 $LCTL set_param fail_loc=0x31c
18783
18784         # ignore failure
18785         $LFS data_version $DIR/$tdir/$tfile || true
18786
18787         do_facet ost1 $LCTL set_param fail_loc=0
18788         umount_client $MOUNT || error "umount failed"
18789         mount_client $MOUNT || error "mount failed"
18790         stop ost1 || error "cannot stop ost1"
18791         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18792 }
18793 run_test 232b "failed data version lock should not block umount"
18794
18795 test_233a() {
18796         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18797                 skip "Need MDS version at least 2.3.64"
18798         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18799
18800         local fid=$($LFS path2fid $MOUNT)
18801
18802         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18803                 error "cannot access $MOUNT using its FID '$fid'"
18804 }
18805 run_test 233a "checking that OBF of the FS root succeeds"
18806
18807 test_233b() {
18808         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18809                 skip "Need MDS version at least 2.5.90"
18810         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18811
18812         local fid=$($LFS path2fid $MOUNT/.lustre)
18813
18814         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18815                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18816
18817         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18818         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18819                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18820 }
18821 run_test 233b "checking that OBF of the FS .lustre succeeds"
18822
18823 test_234() {
18824         local p="$TMP/sanityN-$TESTNAME.parameters"
18825         save_lustre_params client "llite.*.xattr_cache" > $p
18826         lctl set_param llite.*.xattr_cache 1 ||
18827                 skip_env "xattr cache is not supported"
18828
18829         mkdir -p $DIR/$tdir || error "mkdir failed"
18830         touch $DIR/$tdir/$tfile || error "touch failed"
18831         # OBD_FAIL_LLITE_XATTR_ENOMEM
18832         $LCTL set_param fail_loc=0x1405
18833         getfattr -n user.attr $DIR/$tdir/$tfile &&
18834                 error "getfattr should have failed with ENOMEM"
18835         $LCTL set_param fail_loc=0x0
18836         rm -rf $DIR/$tdir
18837
18838         restore_lustre_params < $p
18839         rm -f $p
18840 }
18841 run_test 234 "xattr cache should not crash on ENOMEM"
18842
18843 test_235() {
18844         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18845                 skip "Need MDS version at least 2.4.52"
18846
18847         flock_deadlock $DIR/$tfile
18848         local RC=$?
18849         case $RC in
18850                 0)
18851                 ;;
18852                 124) error "process hangs on a deadlock"
18853                 ;;
18854                 *) error "error executing flock_deadlock $DIR/$tfile"
18855                 ;;
18856         esac
18857 }
18858 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18859
18860 #LU-2935
18861 test_236() {
18862         check_swap_layouts_support
18863
18864         local ref1=/etc/passwd
18865         local ref2=/etc/group
18866         local file1=$DIR/$tdir/f1
18867         local file2=$DIR/$tdir/f2
18868
18869         test_mkdir -c1 $DIR/$tdir
18870         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18871         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18872         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18873         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18874         local fd=$(free_fd)
18875         local cmd="exec $fd<>$file2"
18876         eval $cmd
18877         rm $file2
18878         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18879                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18880         cmd="exec $fd>&-"
18881         eval $cmd
18882         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18883
18884         #cleanup
18885         rm -rf $DIR/$tdir
18886 }
18887 run_test 236 "Layout swap on open unlinked file"
18888
18889 # LU-4659 linkea consistency
18890 test_238() {
18891         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18892                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18893                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18894                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18895
18896         touch $DIR/$tfile
18897         ln $DIR/$tfile $DIR/$tfile.lnk
18898         touch $DIR/$tfile.new
18899         mv $DIR/$tfile.new $DIR/$tfile
18900         local fid1=$($LFS path2fid $DIR/$tfile)
18901         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18902         local path1=$($LFS fid2path $FSNAME "$fid1")
18903         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18904         local path2=$($LFS fid2path $FSNAME "$fid2")
18905         [ $tfile.lnk == $path2 ] ||
18906                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18907         rm -f $DIR/$tfile*
18908 }
18909 run_test 238 "Verify linkea consistency"
18910
18911 test_239A() { # was test_239
18912         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18913                 skip "Need MDS version at least 2.5.60"
18914
18915         local list=$(comma_list $(mdts_nodes))
18916
18917         mkdir -p $DIR/$tdir
18918         createmany -o $DIR/$tdir/f- 5000
18919         unlinkmany $DIR/$tdir/f- 5000
18920         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18921                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18922         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18923                         osp.*MDT*.sync_in_flight" | calc_sum)
18924         [ "$changes" -eq 0 ] || error "$changes not synced"
18925 }
18926 run_test 239A "osp_sync test"
18927
18928 test_239a() { #LU-5297
18929         remote_mds_nodsh && skip "remote MDS with nodsh"
18930
18931         touch $DIR/$tfile
18932         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18933         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18934         chgrp $RUNAS_GID $DIR/$tfile
18935         wait_delete_completed
18936 }
18937 run_test 239a "process invalid osp sync record correctly"
18938
18939 test_239b() { #LU-5297
18940         remote_mds_nodsh && skip "remote MDS with nodsh"
18941
18942         touch $DIR/$tfile1
18943         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18944         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18945         chgrp $RUNAS_GID $DIR/$tfile1
18946         wait_delete_completed
18947         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18948         touch $DIR/$tfile2
18949         chgrp $RUNAS_GID $DIR/$tfile2
18950         wait_delete_completed
18951 }
18952 run_test 239b "process osp sync record with ENOMEM error correctly"
18953
18954 test_240() {
18955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18956         remote_mds_nodsh && skip "remote MDS with nodsh"
18957
18958         mkdir -p $DIR/$tdir
18959
18960         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18961                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18962         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18963                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18964
18965         umount_client $MOUNT || error "umount failed"
18966         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18967         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18968         mount_client $MOUNT || error "failed to mount client"
18969
18970         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18971         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18972 }
18973 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18974
18975 test_241_bio() {
18976         local count=$1
18977         local bsize=$2
18978
18979         for LOOP in $(seq $count); do
18980                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18981                 cancel_lru_locks $OSC || true
18982         done
18983 }
18984
18985 test_241_dio() {
18986         local count=$1
18987         local bsize=$2
18988
18989         for LOOP in $(seq $1); do
18990                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18991                         2>/dev/null
18992         done
18993 }
18994
18995 test_241a() { # was test_241
18996         local bsize=$PAGE_SIZE
18997
18998         (( bsize < 40960 )) && bsize=40960
18999         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19000         ls -la $DIR/$tfile
19001         cancel_lru_locks $OSC
19002         test_241_bio 1000 $bsize &
19003         PID=$!
19004         test_241_dio 1000 $bsize
19005         wait $PID
19006 }
19007 run_test 241a "bio vs dio"
19008
19009 test_241b() {
19010         local bsize=$PAGE_SIZE
19011
19012         (( bsize < 40960 )) && bsize=40960
19013         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19014         ls -la $DIR/$tfile
19015         test_241_dio 1000 $bsize &
19016         PID=$!
19017         test_241_dio 1000 $bsize
19018         wait $PID
19019 }
19020 run_test 241b "dio vs dio"
19021
19022 test_242() {
19023         remote_mds_nodsh && skip "remote MDS with nodsh"
19024
19025         mkdir -p $DIR/$tdir
19026         touch $DIR/$tdir/$tfile
19027
19028         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19029         do_facet mds1 lctl set_param fail_loc=0x105
19030         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19031
19032         do_facet mds1 lctl set_param fail_loc=0
19033         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19034 }
19035 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19036
19037 test_243()
19038 {
19039         test_mkdir $DIR/$tdir
19040         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19041 }
19042 run_test 243 "various group lock tests"
19043
19044 test_244a()
19045 {
19046         test_mkdir $DIR/$tdir
19047         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19048         sendfile_grouplock $DIR/$tdir/$tfile || \
19049                 error "sendfile+grouplock failed"
19050         rm -rf $DIR/$tdir
19051 }
19052 run_test 244a "sendfile with group lock tests"
19053
19054 test_244b()
19055 {
19056         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19057
19058         local threads=50
19059         local size=$((1024*1024))
19060
19061         test_mkdir $DIR/$tdir
19062         for i in $(seq 1 $threads); do
19063                 local file=$DIR/$tdir/file_$((i / 10))
19064                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19065                 local pids[$i]=$!
19066         done
19067         for i in $(seq 1 $threads); do
19068                 wait ${pids[$i]}
19069         done
19070 }
19071 run_test 244b "multi-threaded write with group lock"
19072
19073 test_245() {
19074         local flagname="multi_mod_rpcs"
19075         local connect_data_name="max_mod_rpcs"
19076         local out
19077
19078         # check if multiple modify RPCs flag is set
19079         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19080                 grep "connect_flags:")
19081         echo "$out"
19082
19083         echo "$out" | grep -qw $flagname
19084         if [ $? -ne 0 ]; then
19085                 echo "connect flag $flagname is not set"
19086                 return
19087         fi
19088
19089         # check if multiple modify RPCs data is set
19090         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19091         echo "$out"
19092
19093         echo "$out" | grep -qw $connect_data_name ||
19094                 error "import should have connect data $connect_data_name"
19095 }
19096 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19097
19098 cleanup_247() {
19099         local submount=$1
19100
19101         trap 0
19102         umount_client $submount
19103         rmdir $submount
19104 }
19105
19106 test_247a() {
19107         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19108                 grep -q subtree ||
19109                 skip_env "Fileset feature is not supported"
19110
19111         local submount=${MOUNT}_$tdir
19112
19113         mkdir $MOUNT/$tdir
19114         mkdir -p $submount || error "mkdir $submount failed"
19115         FILESET="$FILESET/$tdir" mount_client $submount ||
19116                 error "mount $submount failed"
19117         trap "cleanup_247 $submount" EXIT
19118         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19119         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19120                 error "read $MOUNT/$tdir/$tfile failed"
19121         cleanup_247 $submount
19122 }
19123 run_test 247a "mount subdir as fileset"
19124
19125 test_247b() {
19126         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19127                 skip_env "Fileset feature is not supported"
19128
19129         local submount=${MOUNT}_$tdir
19130
19131         rm -rf $MOUNT/$tdir
19132         mkdir -p $submount || error "mkdir $submount failed"
19133         SKIP_FILESET=1
19134         FILESET="$FILESET/$tdir" mount_client $submount &&
19135                 error "mount $submount should fail"
19136         rmdir $submount
19137 }
19138 run_test 247b "mount subdir that dose not exist"
19139
19140 test_247c() {
19141         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19142                 skip_env "Fileset feature is not supported"
19143
19144         local submount=${MOUNT}_$tdir
19145
19146         mkdir -p $MOUNT/$tdir/dir1
19147         mkdir -p $submount || error "mkdir $submount failed"
19148         trap "cleanup_247 $submount" EXIT
19149         FILESET="$FILESET/$tdir" mount_client $submount ||
19150                 error "mount $submount failed"
19151         local fid=$($LFS path2fid $MOUNT/)
19152         $LFS fid2path $submount $fid && error "fid2path should fail"
19153         cleanup_247 $submount
19154 }
19155 run_test 247c "running fid2path outside subdirectory root"
19156
19157 test_247d() {
19158         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19159                 skip "Fileset feature is not supported"
19160
19161         local submount=${MOUNT}_$tdir
19162
19163         mkdir -p $MOUNT/$tdir/dir1
19164         mkdir -p $submount || error "mkdir $submount failed"
19165         FILESET="$FILESET/$tdir" mount_client $submount ||
19166                 error "mount $submount failed"
19167         trap "cleanup_247 $submount" EXIT
19168
19169         local td=$submount/dir1
19170         local fid=$($LFS path2fid $td)
19171         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19172
19173         # check that we get the same pathname back
19174         local rootpath
19175         local found
19176         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19177                 echo "$rootpath $fid"
19178                 found=$($LFS fid2path $rootpath "$fid")
19179                 [ -n "found" ] || error "fid2path should succeed"
19180                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19181         done
19182         # check wrong root path format
19183         rootpath=$submount"_wrong"
19184         found=$($LFS fid2path $rootpath "$fid")
19185         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19186
19187         cleanup_247 $submount
19188 }
19189 run_test 247d "running fid2path inside subdirectory root"
19190
19191 # LU-8037
19192 test_247e() {
19193         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19194                 grep -q subtree ||
19195                 skip "Fileset feature is not supported"
19196
19197         local submount=${MOUNT}_$tdir
19198
19199         mkdir $MOUNT/$tdir
19200         mkdir -p $submount || error "mkdir $submount failed"
19201         FILESET="$FILESET/.." mount_client $submount &&
19202                 error "mount $submount should fail"
19203         rmdir $submount
19204 }
19205 run_test 247e "mount .. as fileset"
19206
19207 test_247f() {
19208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19209         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19210                 skip "Need at least version 2.13.52"
19211         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19212                 grep -q subtree ||
19213                 skip "Fileset feature is not supported"
19214
19215         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19216         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19217                 error "mkdir remote failed"
19218         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19219         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19220                 error "mkdir striped failed"
19221         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19222
19223         local submount=${MOUNT}_$tdir
19224
19225         mkdir -p $submount || error "mkdir $submount failed"
19226
19227         local dir
19228         local fileset=$FILESET
19229
19230         for dir in $tdir/remote $tdir/remote/subdir \
19231                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19232                 FILESET="$fileset/$dir" mount_client $submount ||
19233                         error "mount $dir failed"
19234                 umount_client $submount
19235         done
19236 }
19237 run_test 247f "mount striped or remote directory as fileset"
19238
19239 test_248a() {
19240         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19241         [ -z "$fast_read_sav" ] && skip "no fast read support"
19242
19243         # create a large file for fast read verification
19244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19245
19246         # make sure the file is created correctly
19247         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19248                 { rm -f $DIR/$tfile; skip "file creation error"; }
19249
19250         echo "Test 1: verify that fast read is 4 times faster on cache read"
19251
19252         # small read with fast read enabled
19253         $LCTL set_param -n llite.*.fast_read=1
19254         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19255                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19256                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19257         # small read with fast read disabled
19258         $LCTL set_param -n llite.*.fast_read=0
19259         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19260                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19261                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19262
19263         # verify that fast read is 4 times faster for cache read
19264         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19265                 error_not_in_vm "fast read was not 4 times faster: " \
19266                            "$t_fast vs $t_slow"
19267
19268         echo "Test 2: verify the performance between big and small read"
19269         $LCTL set_param -n llite.*.fast_read=1
19270
19271         # 1k non-cache read
19272         cancel_lru_locks osc
19273         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19274                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19275                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19276
19277         # 1M non-cache read
19278         cancel_lru_locks osc
19279         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19280                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19281                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19282
19283         # verify that big IO is not 4 times faster than small IO
19284         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19285                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19286
19287         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19288         rm -f $DIR/$tfile
19289 }
19290 run_test 248a "fast read verification"
19291
19292 test_248b() {
19293         # Default short_io_bytes=16384, try both smaller and larger sizes.
19294         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19295         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19296         echo "bs=53248 count=113 normal buffered write"
19297         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19298                 error "dd of initial data file failed"
19299         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19300
19301         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19302         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19303                 error "dd with sync normal writes failed"
19304         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19305
19306         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19307         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19308                 error "dd with sync small writes failed"
19309         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19310
19311         cancel_lru_locks osc
19312
19313         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19314         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19315         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19316         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19317                 iflag=direct || error "dd with O_DIRECT small read failed"
19318         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19319         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19320                 error "compare $TMP/$tfile.1 failed"
19321
19322         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19323         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19324
19325         # just to see what the maximum tunable value is, and test parsing
19326         echo "test invalid parameter 2MB"
19327         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19328                 error "too-large short_io_bytes allowed"
19329         echo "test maximum parameter 512KB"
19330         # if we can set a larger short_io_bytes, run test regardless of version
19331         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19332                 # older clients may not allow setting it this large, that's OK
19333                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19334                         skip "Need at least client version 2.13.50"
19335                 error "medium short_io_bytes failed"
19336         fi
19337         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19338         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19339
19340         echo "test large parameter 64KB"
19341         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19342         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19343
19344         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19345         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19346                 error "dd with sync large writes failed"
19347         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19348
19349         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19350         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19351         num=$((113 * 4096 / PAGE_SIZE))
19352         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19353         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19354                 error "dd with O_DIRECT large writes failed"
19355         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19356                 error "compare $DIR/$tfile.3 failed"
19357
19358         cancel_lru_locks osc
19359
19360         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19361         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19362                 error "dd with O_DIRECT large read failed"
19363         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19364                 error "compare $TMP/$tfile.2 failed"
19365
19366         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19367         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19368                 error "dd with O_DIRECT large read failed"
19369         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19370                 error "compare $TMP/$tfile.3 failed"
19371 }
19372 run_test 248b "test short_io read and write for both small and large sizes"
19373
19374 test_249() { # LU-7890
19375         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19376                 skip "Need at least version 2.8.54"
19377
19378         rm -f $DIR/$tfile
19379         $LFS setstripe -c 1 $DIR/$tfile
19380         # Offset 2T == 4k * 512M
19381         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19382                 error "dd to 2T offset failed"
19383 }
19384 run_test 249 "Write above 2T file size"
19385
19386 test_250() {
19387         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19388          && skip "no 16TB file size limit on ZFS"
19389
19390         $LFS setstripe -c 1 $DIR/$tfile
19391         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19392         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19393         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19394         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19395                 conv=notrunc,fsync && error "append succeeded"
19396         return 0
19397 }
19398 run_test 250 "Write above 16T limit"
19399
19400 test_251() {
19401         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19402
19403         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19404         #Skip once - writing the first stripe will succeed
19405         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19406         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19407                 error "short write happened"
19408
19409         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19410         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19411                 error "short read happened"
19412
19413         rm -f $DIR/$tfile
19414 }
19415 run_test 251 "Handling short read and write correctly"
19416
19417 test_252() {
19418         remote_mds_nodsh && skip "remote MDS with nodsh"
19419         remote_ost_nodsh && skip "remote OST with nodsh"
19420         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19421                 skip_env "ldiskfs only test"
19422         fi
19423
19424         local tgt
19425         local dev
19426         local out
19427         local uuid
19428         local num
19429         local gen
19430
19431         # check lr_reader on OST0000
19432         tgt=ost1
19433         dev=$(facet_device $tgt)
19434         out=$(do_facet $tgt $LR_READER $dev)
19435         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19436         echo "$out"
19437         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19438         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19439                 error "Invalid uuid returned by $LR_READER on target $tgt"
19440         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19441
19442         # check lr_reader -c on MDT0000
19443         tgt=mds1
19444         dev=$(facet_device $tgt)
19445         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19446                 skip "$LR_READER does not support additional options"
19447         fi
19448         out=$(do_facet $tgt $LR_READER -c $dev)
19449         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19450         echo "$out"
19451         num=$(echo "$out" | grep -c "mdtlov")
19452         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19453                 error "Invalid number of mdtlov clients returned by $LR_READER"
19454         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19455
19456         # check lr_reader -cr on MDT0000
19457         out=$(do_facet $tgt $LR_READER -cr $dev)
19458         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19459         echo "$out"
19460         echo "$out" | grep -q "^reply_data:$" ||
19461                 error "$LR_READER should have returned 'reply_data' section"
19462         num=$(echo "$out" | grep -c "client_generation")
19463         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19464 }
19465 run_test 252 "check lr_reader tool"
19466
19467 test_253() {
19468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19469         remote_mds_nodsh && skip "remote MDS with nodsh"
19470         remote_mgs_nodsh && skip "remote MGS with nodsh"
19471
19472         local ostidx=0
19473         local rc=0
19474         local ost_name=$(ostname_from_index $ostidx)
19475
19476         # on the mdt's osc
19477         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19478         do_facet $SINGLEMDS $LCTL get_param -n \
19479                 osp.$mdtosc_proc1.reserved_mb_high ||
19480                 skip  "remote MDS does not support reserved_mb_high"
19481
19482         rm -rf $DIR/$tdir
19483         wait_mds_ost_sync
19484         wait_delete_completed
19485         mkdir $DIR/$tdir
19486
19487         pool_add $TESTNAME || error "Pool creation failed"
19488         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19489
19490         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19491                 error "Setstripe failed"
19492
19493         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19494
19495         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19496                     grep "watermarks")
19497         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19498
19499         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19500                         osp.$mdtosc_proc1.prealloc_status)
19501         echo "prealloc_status $oa_status"
19502
19503         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19504                 error "File creation should fail"
19505
19506         #object allocation was stopped, but we still able to append files
19507         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19508                 oflag=append || error "Append failed"
19509
19510         rm -f $DIR/$tdir/$tfile.0
19511
19512         # For this test, we want to delete the files we created to go out of
19513         # space but leave the watermark, so we remain nearly out of space
19514         ost_watermarks_enospc_delete_files $tfile $ostidx
19515
19516         wait_delete_completed
19517
19518         sleep_maxage
19519
19520         for i in $(seq 10 12); do
19521                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19522                         2>/dev/null || error "File creation failed after rm"
19523         done
19524
19525         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19526                         osp.$mdtosc_proc1.prealloc_status)
19527         echo "prealloc_status $oa_status"
19528
19529         if (( oa_status != 0 )); then
19530                 error "Object allocation still disable after rm"
19531         fi
19532 }
19533 run_test 253 "Check object allocation limit"
19534
19535 test_254() {
19536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19537         remote_mds_nodsh && skip "remote MDS with nodsh"
19538         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19539                 skip "MDS does not support changelog_size"
19540
19541         local cl_user
19542         local MDT0=$(facet_svc $SINGLEMDS)
19543
19544         changelog_register || error "changelog_register failed"
19545
19546         changelog_clear 0 || error "changelog_clear failed"
19547
19548         local size1=$(do_facet $SINGLEMDS \
19549                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19550         echo "Changelog size $size1"
19551
19552         rm -rf $DIR/$tdir
19553         $LFS mkdir -i 0 $DIR/$tdir
19554         # change something
19555         mkdir -p $DIR/$tdir/pics/2008/zachy
19556         touch $DIR/$tdir/pics/2008/zachy/timestamp
19557         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19558         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19559         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19560         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19561         rm $DIR/$tdir/pics/desktop.jpg
19562
19563         local size2=$(do_facet $SINGLEMDS \
19564                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19565         echo "Changelog size after work $size2"
19566
19567         (( $size2 > $size1 )) ||
19568                 error "new Changelog size=$size2 less than old size=$size1"
19569 }
19570 run_test 254 "Check changelog size"
19571
19572 ladvise_no_type()
19573 {
19574         local type=$1
19575         local file=$2
19576
19577         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19578                 awk -F: '{print $2}' | grep $type > /dev/null
19579         if [ $? -ne 0 ]; then
19580                 return 0
19581         fi
19582         return 1
19583 }
19584
19585 ladvise_no_ioctl()
19586 {
19587         local file=$1
19588
19589         lfs ladvise -a willread $file > /dev/null 2>&1
19590         if [ $? -eq 0 ]; then
19591                 return 1
19592         fi
19593
19594         lfs ladvise -a willread $file 2>&1 |
19595                 grep "Inappropriate ioctl for device" > /dev/null
19596         if [ $? -eq 0 ]; then
19597                 return 0
19598         fi
19599         return 1
19600 }
19601
19602 percent() {
19603         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19604 }
19605
19606 # run a random read IO workload
19607 # usage: random_read_iops <filename> <filesize> <iosize>
19608 random_read_iops() {
19609         local file=$1
19610         local fsize=$2
19611         local iosize=${3:-4096}
19612
19613         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19614                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19615 }
19616
19617 drop_file_oss_cache() {
19618         local file="$1"
19619         local nodes="$2"
19620
19621         $LFS ladvise -a dontneed $file 2>/dev/null ||
19622                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19623 }
19624
19625 ladvise_willread_performance()
19626 {
19627         local repeat=10
19628         local average_origin=0
19629         local average_cache=0
19630         local average_ladvise=0
19631
19632         for ((i = 1; i <= $repeat; i++)); do
19633                 echo "Iter $i/$repeat: reading without willread hint"
19634                 cancel_lru_locks osc
19635                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19636                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19637                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19638                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19639
19640                 cancel_lru_locks osc
19641                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19642                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19643                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19644
19645                 cancel_lru_locks osc
19646                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19647                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19648                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19649                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19650                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19651         done
19652         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19653         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19654         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19655
19656         speedup_cache=$(percent $average_cache $average_origin)
19657         speedup_ladvise=$(percent $average_ladvise $average_origin)
19658
19659         echo "Average uncached read: $average_origin"
19660         echo "Average speedup with OSS cached read: " \
19661                 "$average_cache = +$speedup_cache%"
19662         echo "Average speedup with ladvise willread: " \
19663                 "$average_ladvise = +$speedup_ladvise%"
19664
19665         local lowest_speedup=20
19666         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19667                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19668                         "got $average_cache%. Skipping ladvise willread check."
19669                 return 0
19670         fi
19671
19672         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19673         # it is still good to run until then to exercise 'ladvise willread'
19674         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19675                 [ "$ost1_FSTYPE" = "zfs" ] &&
19676                 echo "osd-zfs does not support dontneed or drop_caches" &&
19677                 return 0
19678
19679         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19680         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19681                 error_not_in_vm "Speedup with willread is less than " \
19682                         "$lowest_speedup%, got $average_ladvise%"
19683 }
19684
19685 test_255a() {
19686         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19687                 skip "lustre < 2.8.54 does not support ladvise "
19688         remote_ost_nodsh && skip "remote OST with nodsh"
19689
19690         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19691
19692         ladvise_no_type willread $DIR/$tfile &&
19693                 skip "willread ladvise is not supported"
19694
19695         ladvise_no_ioctl $DIR/$tfile &&
19696                 skip "ladvise ioctl is not supported"
19697
19698         local size_mb=100
19699         local size=$((size_mb * 1048576))
19700         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19701                 error "dd to $DIR/$tfile failed"
19702
19703         lfs ladvise -a willread $DIR/$tfile ||
19704                 error "Ladvise failed with no range argument"
19705
19706         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19707                 error "Ladvise failed with no -l or -e argument"
19708
19709         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19710                 error "Ladvise failed with only -e argument"
19711
19712         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19713                 error "Ladvise failed with only -l argument"
19714
19715         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19716                 error "End offset should not be smaller than start offset"
19717
19718         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19719                 error "End offset should not be equal to start offset"
19720
19721         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19722                 error "Ladvise failed with overflowing -s argument"
19723
19724         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19725                 error "Ladvise failed with overflowing -e argument"
19726
19727         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19728                 error "Ladvise failed with overflowing -l argument"
19729
19730         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19731                 error "Ladvise succeeded with conflicting -l and -e arguments"
19732
19733         echo "Synchronous ladvise should wait"
19734         local delay=4
19735 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19736         do_nodes $(comma_list $(osts_nodes)) \
19737                 $LCTL set_param fail_val=$delay fail_loc=0x237
19738
19739         local start_ts=$SECONDS
19740         lfs ladvise -a willread $DIR/$tfile ||
19741                 error "Ladvise failed with no range argument"
19742         local end_ts=$SECONDS
19743         local inteval_ts=$((end_ts - start_ts))
19744
19745         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19746                 error "Synchronous advice didn't wait reply"
19747         fi
19748
19749         echo "Asynchronous ladvise shouldn't wait"
19750         local start_ts=$SECONDS
19751         lfs ladvise -a willread -b $DIR/$tfile ||
19752                 error "Ladvise failed with no range argument"
19753         local end_ts=$SECONDS
19754         local inteval_ts=$((end_ts - start_ts))
19755
19756         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19757                 error "Asynchronous advice blocked"
19758         fi
19759
19760         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19761         ladvise_willread_performance
19762 }
19763 run_test 255a "check 'lfs ladvise -a willread'"
19764
19765 facet_meminfo() {
19766         local facet=$1
19767         local info=$2
19768
19769         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19770 }
19771
19772 test_255b() {
19773         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19774                 skip "lustre < 2.8.54 does not support ladvise "
19775         remote_ost_nodsh && skip "remote OST with nodsh"
19776
19777         lfs setstripe -c 1 -i 0 $DIR/$tfile
19778
19779         ladvise_no_type dontneed $DIR/$tfile &&
19780                 skip "dontneed ladvise is not supported"
19781
19782         ladvise_no_ioctl $DIR/$tfile &&
19783                 skip "ladvise ioctl is not supported"
19784
19785         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19786                 [ "$ost1_FSTYPE" = "zfs" ] &&
19787                 skip "zfs-osd does not support 'ladvise dontneed'"
19788
19789         local size_mb=100
19790         local size=$((size_mb * 1048576))
19791         # In order to prevent disturbance of other processes, only check 3/4
19792         # of the memory usage
19793         local kibibytes=$((size_mb * 1024 * 3 / 4))
19794
19795         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19796                 error "dd to $DIR/$tfile failed"
19797
19798         #force write to complete before dropping OST cache & checking memory
19799         sync
19800
19801         local total=$(facet_meminfo ost1 MemTotal)
19802         echo "Total memory: $total KiB"
19803
19804         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19805         local before_read=$(facet_meminfo ost1 Cached)
19806         echo "Cache used before read: $before_read KiB"
19807
19808         lfs ladvise -a willread $DIR/$tfile ||
19809                 error "Ladvise willread failed"
19810         local after_read=$(facet_meminfo ost1 Cached)
19811         echo "Cache used after read: $after_read KiB"
19812
19813         lfs ladvise -a dontneed $DIR/$tfile ||
19814                 error "Ladvise dontneed again failed"
19815         local no_read=$(facet_meminfo ost1 Cached)
19816         echo "Cache used after dontneed ladvise: $no_read KiB"
19817
19818         if [ $total -lt $((before_read + kibibytes)) ]; then
19819                 echo "Memory is too small, abort checking"
19820                 return 0
19821         fi
19822
19823         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19824                 error "Ladvise willread should use more memory" \
19825                         "than $kibibytes KiB"
19826         fi
19827
19828         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19829                 error "Ladvise dontneed should release more memory" \
19830                         "than $kibibytes KiB"
19831         fi
19832 }
19833 run_test 255b "check 'lfs ladvise -a dontneed'"
19834
19835 test_255c() {
19836         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19837                 skip "lustre < 2.10.50 does not support lockahead"
19838
19839         local count
19840         local new_count
19841         local difference
19842         local i
19843         local rc
19844
19845         test_mkdir -p $DIR/$tdir
19846         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19847
19848         #test 10 returns only success/failure
19849         i=10
19850         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19851         rc=$?
19852         if [ $rc -eq 255 ]; then
19853                 error "Ladvise test${i} failed, ${rc}"
19854         fi
19855
19856         #test 11 counts lock enqueue requests, all others count new locks
19857         i=11
19858         count=$(do_facet ost1 \
19859                 $LCTL get_param -n ost.OSS.ost.stats)
19860         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19861
19862         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19863         rc=$?
19864         if [ $rc -eq 255 ]; then
19865                 error "Ladvise test${i} failed, ${rc}"
19866         fi
19867
19868         new_count=$(do_facet ost1 \
19869                 $LCTL get_param -n ost.OSS.ost.stats)
19870         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19871                    awk '{ print $2 }')
19872
19873         difference="$((new_count - count))"
19874         if [ $difference -ne $rc ]; then
19875                 error "Ladvise test${i}, bad enqueue count, returned " \
19876                       "${rc}, actual ${difference}"
19877         fi
19878
19879         for i in $(seq 12 21); do
19880                 # If we do not do this, we run the risk of having too many
19881                 # locks and starting lock cancellation while we are checking
19882                 # lock counts.
19883                 cancel_lru_locks osc
19884
19885                 count=$($LCTL get_param -n \
19886                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19887
19888                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19889                 rc=$?
19890                 if [ $rc -eq 255 ]; then
19891                         error "Ladvise test ${i} failed, ${rc}"
19892                 fi
19893
19894                 new_count=$($LCTL get_param -n \
19895                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19896                 difference="$((new_count - count))"
19897
19898                 # Test 15 output is divided by 100 to map down to valid return
19899                 if [ $i -eq 15 ]; then
19900                         rc="$((rc * 100))"
19901                 fi
19902
19903                 if [ $difference -ne $rc ]; then
19904                         error "Ladvise test ${i}, bad lock count, returned " \
19905                               "${rc}, actual ${difference}"
19906                 fi
19907         done
19908
19909         #test 22 returns only success/failure
19910         i=22
19911         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19912         rc=$?
19913         if [ $rc -eq 255 ]; then
19914                 error "Ladvise test${i} failed, ${rc}"
19915         fi
19916 }
19917 run_test 255c "suite of ladvise lockahead tests"
19918
19919 test_256() {
19920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19921         remote_mds_nodsh && skip "remote MDS with nodsh"
19922         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19923         changelog_users $SINGLEMDS | grep "^cl" &&
19924                 skip "active changelog user"
19925
19926         local cl_user
19927         local cat_sl
19928         local mdt_dev
19929
19930         mdt_dev=$(mdsdevname 1)
19931         echo $mdt_dev
19932
19933         changelog_register || error "changelog_register failed"
19934
19935         rm -rf $DIR/$tdir
19936         mkdir -p $DIR/$tdir
19937
19938         changelog_clear 0 || error "changelog_clear failed"
19939
19940         # change something
19941         touch $DIR/$tdir/{1..10}
19942
19943         # stop the MDT
19944         stop $SINGLEMDS || error "Fail to stop MDT"
19945
19946         # remount the MDT
19947
19948         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19949
19950         #after mount new plainllog is used
19951         touch $DIR/$tdir/{11..19}
19952         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19953         stack_trap "rm -f $tmpfile"
19954         cat_sl=$(do_facet $SINGLEMDS "sync; \
19955                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19956                  llog_reader $tmpfile | grep -c type=1064553b")
19957         do_facet $SINGLEMDS llog_reader $tmpfile
19958
19959         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19960
19961         changelog_clear 0 || error "changelog_clear failed"
19962
19963         cat_sl=$(do_facet $SINGLEMDS "sync; \
19964                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19965                  llog_reader $tmpfile | grep -c type=1064553b")
19966
19967         if (( cat_sl == 2 )); then
19968                 error "Empty plain llog was not deleted from changelog catalog"
19969         elif (( cat_sl != 1 )); then
19970                 error "Active plain llog shouldn't be deleted from catalog"
19971         fi
19972 }
19973 run_test 256 "Check llog delete for empty and not full state"
19974
19975 test_257() {
19976         remote_mds_nodsh && skip "remote MDS with nodsh"
19977         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19978                 skip "Need MDS version at least 2.8.55"
19979
19980         test_mkdir $DIR/$tdir
19981
19982         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19983                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19984         stat $DIR/$tdir
19985
19986 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19987         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19988         local facet=mds$((mdtidx + 1))
19989         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19990         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19991
19992         stop $facet || error "stop MDS failed"
19993         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19994                 error "start MDS fail"
19995         wait_recovery_complete $facet
19996 }
19997 run_test 257 "xattr locks are not lost"
19998
19999 # Verify we take the i_mutex when security requires it
20000 test_258a() {
20001 #define OBD_FAIL_IMUTEX_SEC 0x141c
20002         $LCTL set_param fail_loc=0x141c
20003         touch $DIR/$tfile
20004         chmod u+s $DIR/$tfile
20005         chmod a+rwx $DIR/$tfile
20006         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20007         RC=$?
20008         if [ $RC -ne 0 ]; then
20009                 error "error, failed to take i_mutex, rc=$?"
20010         fi
20011         rm -f $DIR/$tfile
20012 }
20013 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20014
20015 # Verify we do NOT take the i_mutex in the normal case
20016 test_258b() {
20017 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20018         $LCTL set_param fail_loc=0x141d
20019         touch $DIR/$tfile
20020         chmod a+rwx $DIR
20021         chmod a+rw $DIR/$tfile
20022         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20023         RC=$?
20024         if [ $RC -ne 0 ]; then
20025                 error "error, took i_mutex unnecessarily, rc=$?"
20026         fi
20027         rm -f $DIR/$tfile
20028
20029 }
20030 run_test 258b "verify i_mutex security behavior"
20031
20032 test_259() {
20033         local file=$DIR/$tfile
20034         local before
20035         local after
20036
20037         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20038
20039         stack_trap "rm -f $file" EXIT
20040
20041         wait_delete_completed
20042         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20043         echo "before: $before"
20044
20045         $LFS setstripe -i 0 -c 1 $file
20046         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20047         sync_all_data
20048         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20049         echo "after write: $after"
20050
20051 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20052         do_facet ost1 $LCTL set_param fail_loc=0x2301
20053         $TRUNCATE $file 0
20054         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20055         echo "after truncate: $after"
20056
20057         stop ost1
20058         do_facet ost1 $LCTL set_param fail_loc=0
20059         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20060         sleep 2
20061         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20062         echo "after restart: $after"
20063         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20064                 error "missing truncate?"
20065
20066         return 0
20067 }
20068 run_test 259 "crash at delayed truncate"
20069
20070 test_260() {
20071 #define OBD_FAIL_MDC_CLOSE               0x806
20072         $LCTL set_param fail_loc=0x80000806
20073         touch $DIR/$tfile
20074
20075 }
20076 run_test 260 "Check mdc_close fail"
20077
20078 ### Data-on-MDT sanity tests ###
20079 test_270a() {
20080         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20081                 skip "Need MDS version at least 2.10.55 for DoM"
20082
20083         # create DoM file
20084         local dom=$DIR/$tdir/dom_file
20085         local tmp=$DIR/$tdir/tmp_file
20086
20087         mkdir -p $DIR/$tdir
20088
20089         # basic checks for DoM component creation
20090         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20091                 error "Can set MDT layout to non-first entry"
20092
20093         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20094                 error "Can define multiple entries as MDT layout"
20095
20096         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20097
20098         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20099         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20100         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20101
20102         local mdtidx=$($LFS getstripe -m $dom)
20103         local mdtname=MDT$(printf %04x $mdtidx)
20104         local facet=mds$((mdtidx + 1))
20105         local space_check=1
20106
20107         # Skip free space checks with ZFS
20108         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20109
20110         # write
20111         sync
20112         local size_tmp=$((65536 * 3))
20113         local mdtfree1=$(do_facet $facet \
20114                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20115
20116         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20117         # check also direct IO along write
20118         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20119         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20120         sync
20121         cmp $tmp $dom || error "file data is different"
20122         [ $(stat -c%s $dom) == $size_tmp ] ||
20123                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20124         if [ $space_check == 1 ]; then
20125                 local mdtfree2=$(do_facet $facet \
20126                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20127
20128                 # increase in usage from by $size_tmp
20129                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20130                         error "MDT free space wrong after write: " \
20131                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20132         fi
20133
20134         # truncate
20135         local size_dom=10000
20136
20137         $TRUNCATE $dom $size_dom
20138         [ $(stat -c%s $dom) == $size_dom ] ||
20139                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20140         if [ $space_check == 1 ]; then
20141                 mdtfree1=$(do_facet $facet \
20142                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20143                 # decrease in usage from $size_tmp to new $size_dom
20144                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20145                   $(((size_tmp - size_dom) / 1024)) ] ||
20146                         error "MDT free space is wrong after truncate: " \
20147                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20148         fi
20149
20150         # append
20151         cat $tmp >> $dom
20152         sync
20153         size_dom=$((size_dom + size_tmp))
20154         [ $(stat -c%s $dom) == $size_dom ] ||
20155                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20156         if [ $space_check == 1 ]; then
20157                 mdtfree2=$(do_facet $facet \
20158                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20159                 # increase in usage by $size_tmp from previous
20160                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20161                         error "MDT free space is wrong after append: " \
20162                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20163         fi
20164
20165         # delete
20166         rm $dom
20167         if [ $space_check == 1 ]; then
20168                 mdtfree1=$(do_facet $facet \
20169                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20170                 # decrease in usage by $size_dom from previous
20171                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20172                         error "MDT free space is wrong after removal: " \
20173                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20174         fi
20175
20176         # combined striping
20177         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20178                 error "Can't create DoM + OST striping"
20179
20180         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20181         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20182         # check also direct IO along write
20183         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20184         sync
20185         cmp $tmp $dom || error "file data is different"
20186         [ $(stat -c%s $dom) == $size_tmp ] ||
20187                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20188         rm $dom $tmp
20189
20190         return 0
20191 }
20192 run_test 270a "DoM: basic functionality tests"
20193
20194 test_270b() {
20195         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20196                 skip "Need MDS version at least 2.10.55"
20197
20198         local dom=$DIR/$tdir/dom_file
20199         local max_size=1048576
20200
20201         mkdir -p $DIR/$tdir
20202         $LFS setstripe -E $max_size -L mdt $dom
20203
20204         # truncate over the limit
20205         $TRUNCATE $dom $(($max_size + 1)) &&
20206                 error "successful truncate over the maximum size"
20207         # write over the limit
20208         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20209                 error "successful write over the maximum size"
20210         # append over the limit
20211         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20212         echo "12345" >> $dom && error "successful append over the maximum size"
20213         rm $dom
20214
20215         return 0
20216 }
20217 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20218
20219 test_270c() {
20220         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20221                 skip "Need MDS version at least 2.10.55"
20222
20223         mkdir -p $DIR/$tdir
20224         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20225
20226         # check files inherit DoM EA
20227         touch $DIR/$tdir/first
20228         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20229                 error "bad pattern"
20230         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20231                 error "bad stripe count"
20232         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20233                 error "bad stripe size"
20234
20235         # check directory inherits DoM EA and uses it as default
20236         mkdir $DIR/$tdir/subdir
20237         touch $DIR/$tdir/subdir/second
20238         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20239                 error "bad pattern in sub-directory"
20240         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20241                 error "bad stripe count in sub-directory"
20242         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20243                 error "bad stripe size in sub-directory"
20244         return 0
20245 }
20246 run_test 270c "DoM: DoM EA inheritance tests"
20247
20248 test_270d() {
20249         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20250                 skip "Need MDS version at least 2.10.55"
20251
20252         mkdir -p $DIR/$tdir
20253         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20254
20255         # inherit default DoM striping
20256         mkdir $DIR/$tdir/subdir
20257         touch $DIR/$tdir/subdir/f1
20258
20259         # change default directory striping
20260         $LFS setstripe -c 1 $DIR/$tdir/subdir
20261         touch $DIR/$tdir/subdir/f2
20262         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20263                 error "wrong default striping in file 2"
20264         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20265                 error "bad pattern in file 2"
20266         return 0
20267 }
20268 run_test 270d "DoM: change striping from DoM to RAID0"
20269
20270 test_270e() {
20271         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20272                 skip "Need MDS version at least 2.10.55"
20273
20274         mkdir -p $DIR/$tdir/dom
20275         mkdir -p $DIR/$tdir/norm
20276         DOMFILES=20
20277         NORMFILES=10
20278         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20279         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20280
20281         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20282         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20283
20284         # find DoM files by layout
20285         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20286         [ $NUM -eq  $DOMFILES ] ||
20287                 error "lfs find -L: found $NUM, expected $DOMFILES"
20288         echo "Test 1: lfs find 20 DOM files by layout: OK"
20289
20290         # there should be 1 dir with default DOM striping
20291         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20292         [ $NUM -eq  1 ] ||
20293                 error "lfs find -L: found $NUM, expected 1 dir"
20294         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20295
20296         # find DoM files by stripe size
20297         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20298         [ $NUM -eq  $DOMFILES ] ||
20299                 error "lfs find -S: found $NUM, expected $DOMFILES"
20300         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20301
20302         # find files by stripe offset except DoM files
20303         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20304         [ $NUM -eq  $NORMFILES ] ||
20305                 error "lfs find -i: found $NUM, expected $NORMFILES"
20306         echo "Test 5: lfs find no DOM files by stripe index: OK"
20307         return 0
20308 }
20309 run_test 270e "DoM: lfs find with DoM files test"
20310
20311 test_270f() {
20312         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20313                 skip "Need MDS version at least 2.10.55"
20314
20315         local mdtname=${FSNAME}-MDT0000-mdtlov
20316         local dom=$DIR/$tdir/dom_file
20317         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20318                                                 lod.$mdtname.dom_stripesize)
20319         local dom_limit=131072
20320
20321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20322         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20323                                                 lod.$mdtname.dom_stripesize)
20324         [ ${dom_limit} -eq ${dom_current} ] ||
20325                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20326
20327         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20328         $LFS setstripe -d $DIR/$tdir
20329         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20330                 error "Can't set directory default striping"
20331
20332         # exceed maximum stripe size
20333         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20334                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20335         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20336                 error "Able to create DoM component size more than LOD limit"
20337
20338         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20339         dom_current=$(do_facet mds1 $LCTL get_param -n \
20340                                                 lod.$mdtname.dom_stripesize)
20341         [ 0 -eq ${dom_current} ] ||
20342                 error "Can't set zero DoM stripe limit"
20343         rm $dom
20344
20345         # attempt to create DoM file on server with disabled DoM should
20346         # remove DoM entry from layout and be succeed
20347         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20348                 error "Can't create DoM file (DoM is disabled)"
20349         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20350                 error "File has DoM component while DoM is disabled"
20351         rm $dom
20352
20353         # attempt to create DoM file with only DoM stripe should return error
20354         $LFS setstripe -E $dom_limit -L mdt $dom &&
20355                 error "Able to create DoM-only file while DoM is disabled"
20356
20357         # too low values to be aligned with smallest stripe size 64K
20358         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20359         dom_current=$(do_facet mds1 $LCTL get_param -n \
20360                                                 lod.$mdtname.dom_stripesize)
20361         [ 30000 -eq ${dom_current} ] &&
20362                 error "Can set too small DoM stripe limit"
20363
20364         # 64K is a minimal stripe size in Lustre, expect limit of that size
20365         [ 65536 -eq ${dom_current} ] ||
20366                 error "Limit is not set to 64K but ${dom_current}"
20367
20368         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20369         dom_current=$(do_facet mds1 $LCTL get_param -n \
20370                                                 lod.$mdtname.dom_stripesize)
20371         echo $dom_current
20372         [ 2147483648 -eq ${dom_current} ] &&
20373                 error "Can set too large DoM stripe limit"
20374
20375         do_facet mds1 $LCTL set_param -n \
20376                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20377         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20378                 error "Can't create DoM component size after limit change"
20379         do_facet mds1 $LCTL set_param -n \
20380                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20381         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20382                 error "Can't create DoM file after limit decrease"
20383         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20384                 error "Can create big DoM component after limit decrease"
20385         touch ${dom}_def ||
20386                 error "Can't create file with old default layout"
20387
20388         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20389         return 0
20390 }
20391 run_test 270f "DoM: maximum DoM stripe size checks"
20392
20393 test_270g() {
20394         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20395                 skip "Need MDS version at least 2.13.52"
20396         local dom=$DIR/$tdir/$tfile
20397
20398         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20399         local lodname=${FSNAME}-MDT0000-mdtlov
20400
20401         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20402         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20403         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20404         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20405
20406         local dom_limit=1024
20407         local dom_threshold="50%"
20408
20409         $LFS setstripe -d $DIR/$tdir
20410         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20411                 error "Can't set directory default striping"
20412
20413         do_facet mds1 $LCTL set_param -n \
20414                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20415         # set 0 threshold and create DOM file to change tunable stripesize
20416         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20417         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20418                 error "Failed to create $dom file"
20419         # now tunable dom_cur_stripesize should reach maximum
20420         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20421                                         lod.${lodname}.dom_stripesize_cur_kb)
20422         [[ $dom_current == $dom_limit ]] ||
20423                 error "Current DOM stripesize is not maximum"
20424         rm $dom
20425
20426         # set threshold for further tests
20427         do_facet mds1 $LCTL set_param -n \
20428                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20429         echo "DOM threshold is $dom_threshold free space"
20430         local dom_def
20431         local dom_set
20432         # Spoof bfree to exceed threshold
20433         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20434         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20435         for spfree in 40 20 0 15 30 55; do
20436                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20437                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20438                         error "Failed to create $dom file"
20439                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20440                                         lod.${lodname}.dom_stripesize_cur_kb)
20441                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20442                 [[ $dom_def != $dom_current ]] ||
20443                         error "Default stripe size was not changed"
20444                 if [[ $spfree > 0 ]] ; then
20445                         dom_set=$($LFS getstripe -S $dom)
20446                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20447                                 error "DOM component size is still old"
20448                 else
20449                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20450                                 error "DoM component is set with no free space"
20451                 fi
20452                 rm $dom
20453                 dom_current=$dom_def
20454         done
20455 }
20456 run_test 270g "DoM: default DoM stripe size depends on free space"
20457
20458 test_270h() {
20459         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20460                 skip "Need MDS version at least 2.13.53"
20461
20462         local mdtname=${FSNAME}-MDT0000-mdtlov
20463         local dom=$DIR/$tdir/$tfile
20464         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20465
20466         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20467         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20468
20469         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20470         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20471                 error "can't create OST file"
20472         # mirrored file with DOM entry in the second mirror
20473         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20474                 error "can't create mirror with DoM component"
20475
20476         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20477
20478         # DOM component in the middle and has other enries in the same mirror,
20479         # should succeed but lost DoM component
20480         $LFS setstripe --copy=${dom}_1 $dom ||
20481                 error "Can't create file from OST|DOM mirror layout"
20482         # check new file has no DoM layout after all
20483         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20484                 error "File has DoM component while DoM is disabled"
20485 }
20486 run_test 270h "DoM: DoM stripe removal when disabled on server"
20487
20488 test_271a() {
20489         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20490                 skip "Need MDS version at least 2.10.55"
20491
20492         local dom=$DIR/$tdir/dom
20493
20494         mkdir -p $DIR/$tdir
20495
20496         $LFS setstripe -E 1024K -L mdt $dom
20497
20498         lctl set_param -n mdc.*.stats=clear
20499         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20500         cat $dom > /dev/null
20501         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20502         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20503         ls $dom
20504         rm -f $dom
20505 }
20506 run_test 271a "DoM: data is cached for read after write"
20507
20508 test_271b() {
20509         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20510                 skip "Need MDS version at least 2.10.55"
20511
20512         local dom=$DIR/$tdir/dom
20513
20514         mkdir -p $DIR/$tdir
20515
20516         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20517
20518         lctl set_param -n mdc.*.stats=clear
20519         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20520         cancel_lru_locks mdc
20521         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20522         # second stat to check size is cached on client
20523         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20524         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20525         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20526         rm -f $dom
20527 }
20528 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20529
20530 test_271ba() {
20531         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20532                 skip "Need MDS version at least 2.10.55"
20533
20534         local dom=$DIR/$tdir/dom
20535
20536         mkdir -p $DIR/$tdir
20537
20538         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20539
20540         lctl set_param -n mdc.*.stats=clear
20541         lctl set_param -n osc.*.stats=clear
20542         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20543         cancel_lru_locks mdc
20544         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20545         # second stat to check size is cached on client
20546         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20547         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20548         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20549         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20550         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20551         rm -f $dom
20552 }
20553 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20554
20555
20556 get_mdc_stats() {
20557         local mdtidx=$1
20558         local param=$2
20559         local mdt=MDT$(printf %04x $mdtidx)
20560
20561         if [ -z $param ]; then
20562                 lctl get_param -n mdc.*$mdt*.stats
20563         else
20564                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20565         fi
20566 }
20567
20568 test_271c() {
20569         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20570                 skip "Need MDS version at least 2.10.55"
20571
20572         local dom=$DIR/$tdir/dom
20573
20574         mkdir -p $DIR/$tdir
20575
20576         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20577
20578         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20579         local facet=mds$((mdtidx + 1))
20580
20581         cancel_lru_locks mdc
20582         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20583         createmany -o $dom 1000
20584         lctl set_param -n mdc.*.stats=clear
20585         smalliomany -w $dom 1000 200
20586         get_mdc_stats $mdtidx
20587         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20588         # Each file has 1 open, 1 IO enqueues, total 2000
20589         # but now we have also +1 getxattr for security.capability, total 3000
20590         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20591         unlinkmany $dom 1000
20592
20593         cancel_lru_locks mdc
20594         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20595         createmany -o $dom 1000
20596         lctl set_param -n mdc.*.stats=clear
20597         smalliomany -w $dom 1000 200
20598         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20599         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20600         # for OPEN and IO lock.
20601         [ $((enq - enq_2)) -ge 1000 ] ||
20602                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20603         unlinkmany $dom 1000
20604         return 0
20605 }
20606 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20607
20608 cleanup_271def_tests() {
20609         trap 0
20610         rm -f $1
20611 }
20612
20613 test_271d() {
20614         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20615                 skip "Need MDS version at least 2.10.57"
20616
20617         local dom=$DIR/$tdir/dom
20618         local tmp=$TMP/$tfile
20619         trap "cleanup_271def_tests $tmp" EXIT
20620
20621         mkdir -p $DIR/$tdir
20622
20623         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20624
20625         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20626
20627         cancel_lru_locks mdc
20628         dd if=/dev/urandom of=$tmp bs=1000 count=1
20629         dd if=$tmp of=$dom bs=1000 count=1
20630         cancel_lru_locks mdc
20631
20632         cat /etc/hosts >> $tmp
20633         lctl set_param -n mdc.*.stats=clear
20634
20635         # append data to the same file it should update local page
20636         echo "Append to the same page"
20637         cat /etc/hosts >> $dom
20638         local num=$(get_mdc_stats $mdtidx ost_read)
20639         local ra=$(get_mdc_stats $mdtidx req_active)
20640         local rw=$(get_mdc_stats $mdtidx req_waittime)
20641
20642         [ -z $num ] || error "$num READ RPC occured"
20643         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20644         echo "... DONE"
20645
20646         # compare content
20647         cmp $tmp $dom || error "file miscompare"
20648
20649         cancel_lru_locks mdc
20650         lctl set_param -n mdc.*.stats=clear
20651
20652         echo "Open and read file"
20653         cat $dom > /dev/null
20654         local num=$(get_mdc_stats $mdtidx ost_read)
20655         local ra=$(get_mdc_stats $mdtidx req_active)
20656         local rw=$(get_mdc_stats $mdtidx req_waittime)
20657
20658         [ -z $num ] || error "$num READ RPC occured"
20659         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20660         echo "... DONE"
20661
20662         # compare content
20663         cmp $tmp $dom || error "file miscompare"
20664
20665         return 0
20666 }
20667 run_test 271d "DoM: read on open (1K file in reply buffer)"
20668
20669 test_271f() {
20670         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20671                 skip "Need MDS version at least 2.10.57"
20672
20673         local dom=$DIR/$tdir/dom
20674         local tmp=$TMP/$tfile
20675         trap "cleanup_271def_tests $tmp" EXIT
20676
20677         mkdir -p $DIR/$tdir
20678
20679         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20680
20681         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20682
20683         cancel_lru_locks mdc
20684         dd if=/dev/urandom of=$tmp bs=265000 count=1
20685         dd if=$tmp of=$dom bs=265000 count=1
20686         cancel_lru_locks mdc
20687         cat /etc/hosts >> $tmp
20688         lctl set_param -n mdc.*.stats=clear
20689
20690         echo "Append to the same page"
20691         cat /etc/hosts >> $dom
20692         local num=$(get_mdc_stats $mdtidx ost_read)
20693         local ra=$(get_mdc_stats $mdtidx req_active)
20694         local rw=$(get_mdc_stats $mdtidx req_waittime)
20695
20696         [ -z $num ] || error "$num READ RPC occured"
20697         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20698         echo "... DONE"
20699
20700         # compare content
20701         cmp $tmp $dom || error "file miscompare"
20702
20703         cancel_lru_locks mdc
20704         lctl set_param -n mdc.*.stats=clear
20705
20706         echo "Open and read file"
20707         cat $dom > /dev/null
20708         local num=$(get_mdc_stats $mdtidx ost_read)
20709         local ra=$(get_mdc_stats $mdtidx req_active)
20710         local rw=$(get_mdc_stats $mdtidx req_waittime)
20711
20712         [ -z $num ] && num=0
20713         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20714         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20715         echo "... DONE"
20716
20717         # compare content
20718         cmp $tmp $dom || error "file miscompare"
20719
20720         return 0
20721 }
20722 run_test 271f "DoM: read on open (200K file and read tail)"
20723
20724 test_271g() {
20725         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20726                 skip "Skipping due to old client or server version"
20727
20728         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20729         # to get layout
20730         $CHECKSTAT -t file $DIR1/$tfile
20731
20732         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20733         MULTIOP_PID=$!
20734         sleep 1
20735         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20736         $LCTL set_param fail_loc=0x80000314
20737         rm $DIR1/$tfile || error "Unlink fails"
20738         RC=$?
20739         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20740         [ $RC -eq 0 ] || error "Failed write to stale object"
20741 }
20742 run_test 271g "Discard DoM data vs client flush race"
20743
20744 test_272a() {
20745         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20746                 skip "Need MDS version at least 2.11.50"
20747
20748         local dom=$DIR/$tdir/dom
20749         mkdir -p $DIR/$tdir
20750
20751         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20752         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20753                 error "failed to write data into $dom"
20754         local old_md5=$(md5sum $dom)
20755
20756         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20757                 error "failed to migrate to the same DoM component"
20758
20759         local new_md5=$(md5sum $dom)
20760
20761         [ "$old_md5" == "$new_md5" ] ||
20762                 error "md5sum differ: $old_md5, $new_md5"
20763
20764         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20765                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20766 }
20767 run_test 272a "DoM migration: new layout with the same DOM component"
20768
20769 test_272b() {
20770         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20771                 skip "Need MDS version at least 2.11.50"
20772
20773         local dom=$DIR/$tdir/dom
20774         mkdir -p $DIR/$tdir
20775         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20776
20777         local mdtidx=$($LFS getstripe -m $dom)
20778         local mdtname=MDT$(printf %04x $mdtidx)
20779         local facet=mds$((mdtidx + 1))
20780
20781         local mdtfree1=$(do_facet $facet \
20782                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20783         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20784                 error "failed to write data into $dom"
20785         local old_md5=$(md5sum $dom)
20786         cancel_lru_locks mdc
20787         local mdtfree1=$(do_facet $facet \
20788                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20789
20790         $LFS migrate -c2 $dom ||
20791                 error "failed to migrate to the new composite layout"
20792         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20793                 error "MDT stripe was not removed"
20794
20795         cancel_lru_locks mdc
20796         local new_md5=$(md5sum $dom)
20797         [ "$old_md5" == "$new_md5" ] ||
20798                 error "$old_md5 != $new_md5"
20799
20800         # Skip free space checks with ZFS
20801         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20802                 local mdtfree2=$(do_facet $facet \
20803                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20804                 [ $mdtfree2 -gt $mdtfree1 ] ||
20805                         error "MDT space is not freed after migration"
20806         fi
20807         return 0
20808 }
20809 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20810
20811 test_272c() {
20812         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20813                 skip "Need MDS version at least 2.11.50"
20814
20815         local dom=$DIR/$tdir/$tfile
20816         mkdir -p $DIR/$tdir
20817         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20818
20819         local mdtidx=$($LFS getstripe -m $dom)
20820         local mdtname=MDT$(printf %04x $mdtidx)
20821         local facet=mds$((mdtidx + 1))
20822
20823         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20824                 error "failed to write data into $dom"
20825         local old_md5=$(md5sum $dom)
20826         cancel_lru_locks mdc
20827         local mdtfree1=$(do_facet $facet \
20828                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20829
20830         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20831                 error "failed to migrate to the new composite layout"
20832         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20833                 error "MDT stripe was not removed"
20834
20835         cancel_lru_locks mdc
20836         local new_md5=$(md5sum $dom)
20837         [ "$old_md5" == "$new_md5" ] ||
20838                 error "$old_md5 != $new_md5"
20839
20840         # Skip free space checks with ZFS
20841         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20842                 local mdtfree2=$(do_facet $facet \
20843                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20844                 [ $mdtfree2 -gt $mdtfree1 ] ||
20845                         error "MDS space is not freed after migration"
20846         fi
20847         return 0
20848 }
20849 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20850
20851 test_272d() {
20852         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20853                 skip "Need MDS version at least 2.12.55"
20854
20855         local dom=$DIR/$tdir/$tfile
20856         mkdir -p $DIR/$tdir
20857         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20858
20859         local mdtidx=$($LFS getstripe -m $dom)
20860         local mdtname=MDT$(printf %04x $mdtidx)
20861         local facet=mds$((mdtidx + 1))
20862
20863         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20864                 error "failed to write data into $dom"
20865         local old_md5=$(md5sum $dom)
20866         cancel_lru_locks mdc
20867         local mdtfree1=$(do_facet $facet \
20868                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20869
20870         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20871                 error "failed mirroring to the new composite layout"
20872         $LFS mirror resync $dom ||
20873                 error "failed mirror resync"
20874         $LFS mirror split --mirror-id 1 -d $dom ||
20875                 error "failed mirror split"
20876
20877         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20878                 error "MDT stripe was not removed"
20879
20880         cancel_lru_locks mdc
20881         local new_md5=$(md5sum $dom)
20882         [ "$old_md5" == "$new_md5" ] ||
20883                 error "$old_md5 != $new_md5"
20884
20885         # Skip free space checks with ZFS
20886         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20887                 local mdtfree2=$(do_facet $facet \
20888                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20889                 [ $mdtfree2 -gt $mdtfree1 ] ||
20890                         error "MDS space is not freed after DOM mirror deletion"
20891         fi
20892         return 0
20893 }
20894 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20895
20896 test_272e() {
20897         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20898                 skip "Need MDS version at least 2.12.55"
20899
20900         local dom=$DIR/$tdir/$tfile
20901         mkdir -p $DIR/$tdir
20902         $LFS setstripe -c 2 $dom
20903
20904         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20905                 error "failed to write data into $dom"
20906         local old_md5=$(md5sum $dom)
20907         cancel_lru_locks mdc
20908
20909         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20910                 error "failed mirroring to the DOM layout"
20911         $LFS mirror resync $dom ||
20912                 error "failed mirror resync"
20913         $LFS mirror split --mirror-id 1 -d $dom ||
20914                 error "failed mirror split"
20915
20916         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20917                 error "MDT stripe was not removed"
20918
20919         cancel_lru_locks mdc
20920         local new_md5=$(md5sum $dom)
20921         [ "$old_md5" == "$new_md5" ] ||
20922                 error "$old_md5 != $new_md5"
20923
20924         return 0
20925 }
20926 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20927
20928 test_272f() {
20929         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20930                 skip "Need MDS version at least 2.12.55"
20931
20932         local dom=$DIR/$tdir/$tfile
20933         mkdir -p $DIR/$tdir
20934         $LFS setstripe -c 2 $dom
20935
20936         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20937                 error "failed to write data into $dom"
20938         local old_md5=$(md5sum $dom)
20939         cancel_lru_locks mdc
20940
20941         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20942                 error "failed migrating to the DOM file"
20943
20944         cancel_lru_locks mdc
20945         local new_md5=$(md5sum $dom)
20946         [ "$old_md5" != "$new_md5" ] &&
20947                 error "$old_md5 != $new_md5"
20948
20949         return 0
20950 }
20951 run_test 272f "DoM migration: OST-striped file to DOM file"
20952
20953 test_273a() {
20954         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20955                 skip "Need MDS version at least 2.11.50"
20956
20957         # Layout swap cannot be done if either file has DOM component,
20958         # this will never be supported, migration should be used instead
20959
20960         local dom=$DIR/$tdir/$tfile
20961         mkdir -p $DIR/$tdir
20962
20963         $LFS setstripe -c2 ${dom}_plain
20964         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20965         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20966                 error "can swap layout with DoM component"
20967         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20968                 error "can swap layout with DoM component"
20969
20970         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20971         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20972                 error "can swap layout with DoM component"
20973         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20974                 error "can swap layout with DoM component"
20975         return 0
20976 }
20977 run_test 273a "DoM: layout swapping should fail with DOM"
20978
20979 test_275() {
20980         remote_ost_nodsh && skip "remote OST with nodsh"
20981         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20982                 skip "Need OST version >= 2.10.57"
20983
20984         local file=$DIR/$tfile
20985         local oss
20986
20987         oss=$(comma_list $(osts_nodes))
20988
20989         dd if=/dev/urandom of=$file bs=1M count=2 ||
20990                 error "failed to create a file"
20991         cancel_lru_locks osc
20992
20993         #lock 1
20994         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20995                 error "failed to read a file"
20996
20997 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20998         $LCTL set_param fail_loc=0x8000031f
20999
21000         cancel_lru_locks osc &
21001         sleep 1
21002
21003 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21004         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21005         #IO takes another lock, but matches the PENDING one
21006         #and places it to the IO RPC
21007         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21008                 error "failed to read a file with PENDING lock"
21009 }
21010 run_test 275 "Read on a canceled duplicate lock"
21011
21012 test_276() {
21013         remote_ost_nodsh && skip "remote OST with nodsh"
21014         local pid
21015
21016         do_facet ost1 "(while true; do \
21017                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21018                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21019         pid=$!
21020
21021         for LOOP in $(seq 20); do
21022                 stop ost1
21023                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21024         done
21025         kill -9 $pid
21026         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21027                 rm $TMP/sanity_276_pid"
21028 }
21029 run_test 276 "Race between mount and obd_statfs"
21030
21031 test_277() {
21032         $LCTL set_param ldlm.namespaces.*.lru_size=0
21033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21034         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21035                         grep ^used_mb | awk '{print $2}')
21036         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21038                 oflag=direct conv=notrunc
21039         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21040                         grep ^used_mb | awk '{print $2}')
21041         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21042 }
21043 run_test 277 "Direct IO shall drop page cache"
21044
21045 test_278() {
21046         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21047         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21048         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21049                 skip "needs the same host for mdt1 mdt2" && return
21050
21051         local pid1
21052         local pid2
21053
21054 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21055         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21056         stop mds2 &
21057         pid2=$!
21058
21059         stop mds1
21060
21061         echo "Starting MDTs"
21062         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21063         wait $pid2
21064 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21065 #will return NULL
21066         do_facet mds2 $LCTL set_param fail_loc=0
21067
21068         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21069         wait_recovery_complete mds2
21070 }
21071 run_test 278 "Race starting MDS between MDTs stop/start"
21072
21073 test_280() {
21074         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21075                 skip "Need MGS version at least 2.13.52"
21076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21077         combined_mgs_mds || skip "needs combined MGS/MDT"
21078
21079         umount_client $MOUNT
21080 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21081         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21082
21083         mount_client $MOUNT &
21084         sleep 1
21085         stop mgs || error "stop mgs failed"
21086         #for a race mgs would crash
21087         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21088         mount_client $MOUNT || error "mount client failed"
21089 }
21090 run_test 280 "Race between MGS umount and client llog processing"
21091
21092 cleanup_test_300() {
21093         trap 0
21094         umask $SAVE_UMASK
21095 }
21096 test_striped_dir() {
21097         local mdt_index=$1
21098         local stripe_count
21099         local stripe_index
21100
21101         mkdir -p $DIR/$tdir
21102
21103         SAVE_UMASK=$(umask)
21104         trap cleanup_test_300 RETURN EXIT
21105
21106         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21107                                                 $DIR/$tdir/striped_dir ||
21108                 error "set striped dir error"
21109
21110         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21111         [ "$mode" = "755" ] || error "expect 755 got $mode"
21112
21113         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21114                 error "getdirstripe failed"
21115         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21116         if [ "$stripe_count" != "2" ]; then
21117                 error "1:stripe_count is $stripe_count, expect 2"
21118         fi
21119         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21120         if [ "$stripe_count" != "2" ]; then
21121                 error "2:stripe_count is $stripe_count, expect 2"
21122         fi
21123
21124         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21125         if [ "$stripe_index" != "$mdt_index" ]; then
21126                 error "stripe_index is $stripe_index, expect $mdt_index"
21127         fi
21128
21129         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21130                 error "nlink error after create striped dir"
21131
21132         mkdir $DIR/$tdir/striped_dir/a
21133         mkdir $DIR/$tdir/striped_dir/b
21134
21135         stat $DIR/$tdir/striped_dir/a ||
21136                 error "create dir under striped dir failed"
21137         stat $DIR/$tdir/striped_dir/b ||
21138                 error "create dir under striped dir failed"
21139
21140         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21141                 error "nlink error after mkdir"
21142
21143         rmdir $DIR/$tdir/striped_dir/a
21144         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21145                 error "nlink error after rmdir"
21146
21147         rmdir $DIR/$tdir/striped_dir/b
21148         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21149                 error "nlink error after rmdir"
21150
21151         chattr +i $DIR/$tdir/striped_dir
21152         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21153                 error "immutable flags not working under striped dir!"
21154         chattr -i $DIR/$tdir/striped_dir
21155
21156         rmdir $DIR/$tdir/striped_dir ||
21157                 error "rmdir striped dir error"
21158
21159         cleanup_test_300
21160
21161         true
21162 }
21163
21164 test_300a() {
21165         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21166                 skip "skipped for lustre < 2.7.0"
21167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21169
21170         test_striped_dir 0 || error "failed on striped dir on MDT0"
21171         test_striped_dir 1 || error "failed on striped dir on MDT0"
21172 }
21173 run_test 300a "basic striped dir sanity test"
21174
21175 test_300b() {
21176         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21177                 skip "skipped for lustre < 2.7.0"
21178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21180
21181         local i
21182         local mtime1
21183         local mtime2
21184         local mtime3
21185
21186         test_mkdir $DIR/$tdir || error "mkdir fail"
21187         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21188                 error "set striped dir error"
21189         for i in {0..9}; do
21190                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21191                 sleep 1
21192                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21193                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21194                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21195                 sleep 1
21196                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21197                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21198                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21199         done
21200         true
21201 }
21202 run_test 300b "check ctime/mtime for striped dir"
21203
21204 test_300c() {
21205         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21206                 skip "skipped for lustre < 2.7.0"
21207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21209
21210         local file_count
21211
21212         mkdir -p $DIR/$tdir
21213         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21214                 error "set striped dir error"
21215
21216         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21217                 error "chown striped dir failed"
21218
21219         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21220                 error "create 5k files failed"
21221
21222         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21223
21224         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21225
21226         rm -rf $DIR/$tdir
21227 }
21228 run_test 300c "chown && check ls under striped directory"
21229
21230 test_300d() {
21231         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21232                 skip "skipped for lustre < 2.7.0"
21233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21235
21236         local stripe_count
21237         local file
21238
21239         mkdir -p $DIR/$tdir
21240         $LFS setstripe -c 2 $DIR/$tdir
21241
21242         #local striped directory
21243         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21244                 error "set striped dir error"
21245         #look at the directories for debug purposes
21246         ls -l $DIR/$tdir
21247         $LFS getdirstripe $DIR/$tdir
21248         ls -l $DIR/$tdir/striped_dir
21249         $LFS getdirstripe $DIR/$tdir/striped_dir
21250         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21251                 error "create 10 files failed"
21252
21253         #remote striped directory
21254         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21255                 error "set striped dir error"
21256         #look at the directories for debug purposes
21257         ls -l $DIR/$tdir
21258         $LFS getdirstripe $DIR/$tdir
21259         ls -l $DIR/$tdir/remote_striped_dir
21260         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21261         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21262                 error "create 10 files failed"
21263
21264         for file in $(find $DIR/$tdir); do
21265                 stripe_count=$($LFS getstripe -c $file)
21266                 [ $stripe_count -eq 2 ] ||
21267                         error "wrong stripe $stripe_count for $file"
21268         done
21269
21270         rm -rf $DIR/$tdir
21271 }
21272 run_test 300d "check default stripe under striped directory"
21273
21274 test_300e() {
21275         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21276                 skip "Need MDS version at least 2.7.55"
21277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21279
21280         local stripe_count
21281         local file
21282
21283         mkdir -p $DIR/$tdir
21284
21285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21286                 error "set striped dir error"
21287
21288         touch $DIR/$tdir/striped_dir/a
21289         touch $DIR/$tdir/striped_dir/b
21290         touch $DIR/$tdir/striped_dir/c
21291
21292         mkdir $DIR/$tdir/striped_dir/dir_a
21293         mkdir $DIR/$tdir/striped_dir/dir_b
21294         mkdir $DIR/$tdir/striped_dir/dir_c
21295
21296         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21297                 error "set striped adir under striped dir error"
21298
21299         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21300                 error "set striped bdir under striped dir error"
21301
21302         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21303                 error "set striped cdir under striped dir error"
21304
21305         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21306                 error "rename dir under striped dir fails"
21307
21308         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21309                 error "rename dir under different stripes fails"
21310
21311         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21312                 error "rename file under striped dir should succeed"
21313
21314         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21315                 error "rename dir under striped dir should succeed"
21316
21317         rm -rf $DIR/$tdir
21318 }
21319 run_test 300e "check rename under striped directory"
21320
21321 test_300f() {
21322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21324         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21325                 skip "Need MDS version at least 2.7.55"
21326
21327         local stripe_count
21328         local file
21329
21330         rm -rf $DIR/$tdir
21331         mkdir -p $DIR/$tdir
21332
21333         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21334                 error "set striped dir error"
21335
21336         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21337                 error "set striped dir error"
21338
21339         touch $DIR/$tdir/striped_dir/a
21340         mkdir $DIR/$tdir/striped_dir/dir_a
21341         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21342                 error "create striped dir under striped dir fails"
21343
21344         touch $DIR/$tdir/striped_dir1/b
21345         mkdir $DIR/$tdir/striped_dir1/dir_b
21346         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21347                 error "create striped dir under striped dir fails"
21348
21349         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21350                 error "rename dir under different striped dir should fail"
21351
21352         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21353                 error "rename striped dir under diff striped dir should fail"
21354
21355         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21356                 error "rename file under diff striped dirs fails"
21357
21358         rm -rf $DIR/$tdir
21359 }
21360 run_test 300f "check rename cross striped directory"
21361
21362 test_300_check_default_striped_dir()
21363 {
21364         local dirname=$1
21365         local default_count=$2
21366         local default_index=$3
21367         local stripe_count
21368         local stripe_index
21369         local dir_stripe_index
21370         local dir
21371
21372         echo "checking $dirname $default_count $default_index"
21373         $LFS setdirstripe -D -c $default_count -i $default_index \
21374                                 -t all_char $DIR/$tdir/$dirname ||
21375                 error "set default stripe on striped dir error"
21376         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21377         [ $stripe_count -eq $default_count ] ||
21378                 error "expect $default_count get $stripe_count for $dirname"
21379
21380         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21381         [ $stripe_index -eq $default_index ] ||
21382                 error "expect $default_index get $stripe_index for $dirname"
21383
21384         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21385                                                 error "create dirs failed"
21386
21387         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21388         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21389         for dir in $(find $DIR/$tdir/$dirname/*); do
21390                 stripe_count=$($LFS getdirstripe -c $dir)
21391                 [ $stripe_count -eq $default_count ] ||
21392                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21393                 error "stripe count $default_count != $stripe_count for $dir"
21394
21395                 stripe_index=$($LFS getdirstripe -i $dir)
21396                 [ $default_index -eq -1 ] ||
21397                         [ $stripe_index -eq $default_index ] ||
21398                         error "$stripe_index != $default_index for $dir"
21399
21400                 #check default stripe
21401                 stripe_count=$($LFS getdirstripe -D -c $dir)
21402                 [ $stripe_count -eq $default_count ] ||
21403                 error "default count $default_count != $stripe_count for $dir"
21404
21405                 stripe_index=$($LFS getdirstripe -D -i $dir)
21406                 [ $stripe_index -eq $default_index ] ||
21407                 error "default index $default_index != $stripe_index for $dir"
21408         done
21409         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21410 }
21411
21412 test_300g() {
21413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21415                 skip "Need MDS version at least 2.7.55"
21416
21417         local dir
21418         local stripe_count
21419         local stripe_index
21420
21421         mkdir $DIR/$tdir
21422         mkdir $DIR/$tdir/normal_dir
21423
21424         #Checking when client cache stripe index
21425         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21426         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21427                 error "create striped_dir failed"
21428
21429         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21430                 error "create dir0 fails"
21431         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21432         [ $stripe_index -eq 0 ] ||
21433                 error "dir0 expect index 0 got $stripe_index"
21434
21435         mkdir $DIR/$tdir/striped_dir/dir1 ||
21436                 error "create dir1 fails"
21437         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21438         [ $stripe_index -eq 1 ] ||
21439                 error "dir1 expect index 1 got $stripe_index"
21440
21441         #check default stripe count/stripe index
21442         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21443         test_300_check_default_striped_dir normal_dir 1 0
21444         test_300_check_default_striped_dir normal_dir 2 1
21445         test_300_check_default_striped_dir normal_dir 2 -1
21446
21447         #delete default stripe information
21448         echo "delete default stripeEA"
21449         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21450                 error "set default stripe on striped dir error"
21451
21452         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21453         for dir in $(find $DIR/$tdir/normal_dir/*); do
21454                 stripe_count=$($LFS getdirstripe -c $dir)
21455                 [ $stripe_count -eq 0 ] ||
21456                         error "expect 1 get $stripe_count for $dir"
21457                 stripe_index=$($LFS getdirstripe -i $dir)
21458                 [ $stripe_index -eq 0 ] ||
21459                         error "expect 0 get $stripe_index for $dir"
21460         done
21461 }
21462 run_test 300g "check default striped directory for normal directory"
21463
21464 test_300h() {
21465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21466         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21467                 skip "Need MDS version at least 2.7.55"
21468
21469         local dir
21470         local stripe_count
21471
21472         mkdir $DIR/$tdir
21473         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21474                 error "set striped dir error"
21475
21476         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21477         test_300_check_default_striped_dir striped_dir 1 0
21478         test_300_check_default_striped_dir striped_dir 2 1
21479         test_300_check_default_striped_dir striped_dir 2 -1
21480
21481         #delete default stripe information
21482         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21483                 error "set default stripe on striped dir error"
21484
21485         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21486         for dir in $(find $DIR/$tdir/striped_dir/*); do
21487                 stripe_count=$($LFS getdirstripe -c $dir)
21488                 [ $stripe_count -eq 0 ] ||
21489                         error "expect 1 get $stripe_count for $dir"
21490         done
21491 }
21492 run_test 300h "check default striped directory for striped directory"
21493
21494 test_300i() {
21495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21498                 skip "Need MDS version at least 2.7.55"
21499
21500         local stripe_count
21501         local file
21502
21503         mkdir $DIR/$tdir
21504
21505         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21506                 error "set striped dir error"
21507
21508         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21509                 error "create files under striped dir failed"
21510
21511         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21512                 error "set striped hashdir error"
21513
21514         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21515                 error "create dir0 under hash dir failed"
21516         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21517                 error "create dir1 under hash dir failed"
21518
21519         # unfortunately, we need to umount to clear dir layout cache for now
21520         # once we fully implement dir layout, we can drop this
21521         umount_client $MOUNT || error "umount failed"
21522         mount_client $MOUNT || error "mount failed"
21523
21524         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21525         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21526         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21527
21528         #set the stripe to be unknown hash type
21529         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21530         $LCTL set_param fail_loc=0x1901
21531         for ((i = 0; i < 10; i++)); do
21532                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21533                         error "stat f-$i failed"
21534                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21535         done
21536
21537         touch $DIR/$tdir/striped_dir/f0 &&
21538                 error "create under striped dir with unknown hash should fail"
21539
21540         $LCTL set_param fail_loc=0
21541
21542         umount_client $MOUNT || error "umount failed"
21543         mount_client $MOUNT || error "mount failed"
21544
21545         return 0
21546 }
21547 run_test 300i "client handle unknown hash type striped directory"
21548
21549 test_300j() {
21550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21552         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21553                 skip "Need MDS version at least 2.7.55"
21554
21555         local stripe_count
21556         local file
21557
21558         mkdir $DIR/$tdir
21559
21560         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21561         $LCTL set_param fail_loc=0x1702
21562         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21563                 error "set striped dir error"
21564
21565         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21566                 error "create files under striped dir failed"
21567
21568         $LCTL set_param fail_loc=0
21569
21570         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21571
21572         return 0
21573 }
21574 run_test 300j "test large update record"
21575
21576 test_300k() {
21577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21579         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21580                 skip "Need MDS version at least 2.7.55"
21581
21582         # this test needs a huge transaction
21583         local kb
21584         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21585              osd*.$FSNAME-MDT0000.kbytestotal")
21586         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21587
21588         local stripe_count
21589         local file
21590
21591         mkdir $DIR/$tdir
21592
21593         #define OBD_FAIL_LARGE_STRIPE   0x1703
21594         $LCTL set_param fail_loc=0x1703
21595         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21596                 error "set striped dir error"
21597         $LCTL set_param fail_loc=0
21598
21599         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21600                 error "getstripeddir fails"
21601         rm -rf $DIR/$tdir/striped_dir ||
21602                 error "unlink striped dir fails"
21603
21604         return 0
21605 }
21606 run_test 300k "test large striped directory"
21607
21608 test_300l() {
21609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21611         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21612                 skip "Need MDS version at least 2.7.55"
21613
21614         local stripe_index
21615
21616         test_mkdir -p $DIR/$tdir/striped_dir
21617         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21618                         error "chown $RUNAS_ID failed"
21619         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21620                 error "set default striped dir failed"
21621
21622         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21623         $LCTL set_param fail_loc=0x80000158
21624         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21625
21626         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21627         [ $stripe_index -eq 1 ] ||
21628                 error "expect 1 get $stripe_index for $dir"
21629 }
21630 run_test 300l "non-root user to create dir under striped dir with stale layout"
21631
21632 test_300m() {
21633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21634         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21635         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21636                 skip "Need MDS version at least 2.7.55"
21637
21638         mkdir -p $DIR/$tdir/striped_dir
21639         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21640                 error "set default stripes dir error"
21641
21642         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21643
21644         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21645         [ $stripe_count -eq 0 ] ||
21646                         error "expect 0 get $stripe_count for a"
21647
21648         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21649                 error "set default stripes dir error"
21650
21651         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21652
21653         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21654         [ $stripe_count -eq 0 ] ||
21655                         error "expect 0 get $stripe_count for b"
21656
21657         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21658                 error "set default stripes dir error"
21659
21660         mkdir $DIR/$tdir/striped_dir/c &&
21661                 error "default stripe_index is invalid, mkdir c should fails"
21662
21663         rm -rf $DIR/$tdir || error "rmdir fails"
21664 }
21665 run_test 300m "setstriped directory on single MDT FS"
21666
21667 cleanup_300n() {
21668         local list=$(comma_list $(mdts_nodes))
21669
21670         trap 0
21671         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21672 }
21673
21674 test_300n() {
21675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21678                 skip "Need MDS version at least 2.7.55"
21679         remote_mds_nodsh && skip "remote MDS with nodsh"
21680
21681         local stripe_index
21682         local list=$(comma_list $(mdts_nodes))
21683
21684         trap cleanup_300n RETURN EXIT
21685         mkdir -p $DIR/$tdir
21686         chmod 777 $DIR/$tdir
21687         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21688                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21689                 error "create striped dir succeeds with gid=0"
21690
21691         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21692         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21693                 error "create striped dir fails with gid=-1"
21694
21695         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21696         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21697                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21698                 error "set default striped dir succeeds with gid=0"
21699
21700
21701         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21702         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21703                 error "set default striped dir fails with gid=-1"
21704
21705
21706         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21707         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21708                                         error "create test_dir fails"
21709         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21710                                         error "create test_dir1 fails"
21711         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21712                                         error "create test_dir2 fails"
21713         cleanup_300n
21714 }
21715 run_test 300n "non-root user to create dir under striped dir with default EA"
21716
21717 test_300o() {
21718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21721                 skip "Need MDS version at least 2.7.55"
21722
21723         local numfree1
21724         local numfree2
21725
21726         mkdir -p $DIR/$tdir
21727
21728         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21729         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21730         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21731                 skip "not enough free inodes $numfree1 $numfree2"
21732         fi
21733
21734         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21735         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21736         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21737                 skip "not enough free space $numfree1 $numfree2"
21738         fi
21739
21740         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21741                 error "setdirstripe fails"
21742
21743         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21744                 error "create dirs fails"
21745
21746         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21747         ls $DIR/$tdir/striped_dir > /dev/null ||
21748                 error "ls striped dir fails"
21749         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21750                 error "unlink big striped dir fails"
21751 }
21752 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21753
21754 test_300p() {
21755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21756         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21757         remote_mds_nodsh && skip "remote MDS with nodsh"
21758
21759         mkdir -p $DIR/$tdir
21760
21761         #define OBD_FAIL_OUT_ENOSPC     0x1704
21762         do_facet mds2 lctl set_param fail_loc=0x80001704
21763         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21764                  && error "create striped directory should fail"
21765
21766         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21767
21768         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21769         true
21770 }
21771 run_test 300p "create striped directory without space"
21772
21773 test_300q() {
21774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21775         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21776
21777         local fd=$(free_fd)
21778         local cmd="exec $fd<$tdir"
21779         cd $DIR
21780         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21781         eval $cmd
21782         cmd="exec $fd<&-"
21783         trap "eval $cmd" EXIT
21784         cd $tdir || error "cd $tdir fails"
21785         rmdir  ../$tdir || error "rmdir $tdir fails"
21786         mkdir local_dir && error "create dir succeeds"
21787         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21788         eval $cmd
21789         return 0
21790 }
21791 run_test 300q "create remote directory under orphan directory"
21792
21793 test_300r() {
21794         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21795                 skip "Need MDS version at least 2.7.55" && return
21796         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21797
21798         mkdir $DIR/$tdir
21799
21800         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21801                 error "set striped dir error"
21802
21803         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21804                 error "getstripeddir fails"
21805
21806         local stripe_count
21807         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21808                       awk '/lmv_stripe_count:/ { print $2 }')
21809
21810         [ $MDSCOUNT -ne $stripe_count ] &&
21811                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21812
21813         rm -rf $DIR/$tdir/striped_dir ||
21814                 error "unlink striped dir fails"
21815 }
21816 run_test 300r "test -1 striped directory"
21817
21818 test_300s_helper() {
21819         local count=$1
21820
21821         local stripe_dir=$DIR/$tdir/striped_dir.$count
21822
21823         $LFS mkdir -c $count $stripe_dir ||
21824                 error "lfs mkdir -c error"
21825
21826         $LFS getdirstripe $stripe_dir ||
21827                 error "lfs getdirstripe fails"
21828
21829         local stripe_count
21830         stripe_count=$($LFS getdirstripe $stripe_dir |
21831                       awk '/lmv_stripe_count:/ { print $2 }')
21832
21833         [ $count -ne $stripe_count ] &&
21834                 error_noexit "bad stripe count $stripe_count expected $count"
21835
21836         local dupe_stripes
21837         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21838                 awk '/0x/ {count[$1] += 1}; END {
21839                         for (idx in count) {
21840                                 if (count[idx]>1) {
21841                                         print "index " idx " count " count[idx]
21842                                 }
21843                         }
21844                 }')
21845
21846         if [[ -n "$dupe_stripes" ]] ; then
21847                 lfs getdirstripe $stripe_dir
21848                 error_noexit "Dupe MDT above: $dupe_stripes "
21849         fi
21850
21851         rm -rf $stripe_dir ||
21852                 error_noexit "unlink $stripe_dir fails"
21853 }
21854
21855 test_300s() {
21856         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21857                 skip "Need MDS version at least 2.7.55" && return
21858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21859
21860         mkdir $DIR/$tdir
21861         for count in $(seq 2 $MDSCOUNT); do
21862                 test_300s_helper $count
21863         done
21864 }
21865 run_test 300s "test lfs mkdir -c without -i"
21866
21867
21868 prepare_remote_file() {
21869         mkdir $DIR/$tdir/src_dir ||
21870                 error "create remote source failed"
21871
21872         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21873                  error "cp to remote source failed"
21874         touch $DIR/$tdir/src_dir/a
21875
21876         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21877                 error "create remote target dir failed"
21878
21879         touch $DIR/$tdir/tgt_dir/b
21880
21881         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21882                 error "rename dir cross MDT failed!"
21883
21884         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21885                 error "src_child still exists after rename"
21886
21887         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21888                 error "missing file(a) after rename"
21889
21890         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21891                 error "diff after rename"
21892 }
21893
21894 test_310a() {
21895         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21897
21898         local remote_file=$DIR/$tdir/tgt_dir/b
21899
21900         mkdir -p $DIR/$tdir
21901
21902         prepare_remote_file || error "prepare remote file failed"
21903
21904         #open-unlink file
21905         $OPENUNLINK $remote_file $remote_file ||
21906                 error "openunlink $remote_file failed"
21907         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21908 }
21909 run_test 310a "open unlink remote file"
21910
21911 test_310b() {
21912         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21914
21915         local remote_file=$DIR/$tdir/tgt_dir/b
21916
21917         mkdir -p $DIR/$tdir
21918
21919         prepare_remote_file || error "prepare remote file failed"
21920
21921         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21922         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21923         $CHECKSTAT -t file $remote_file || error "check file failed"
21924 }
21925 run_test 310b "unlink remote file with multiple links while open"
21926
21927 test_310c() {
21928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21929         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21930
21931         local remote_file=$DIR/$tdir/tgt_dir/b
21932
21933         mkdir -p $DIR/$tdir
21934
21935         prepare_remote_file || error "prepare remote file failed"
21936
21937         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21938         multiop_bg_pause $remote_file O_uc ||
21939                         error "mulitop failed for remote file"
21940         MULTIPID=$!
21941         $MULTIOP $DIR/$tfile Ouc
21942         kill -USR1 $MULTIPID
21943         wait $MULTIPID
21944 }
21945 run_test 310c "open-unlink remote file with multiple links"
21946
21947 #LU-4825
21948 test_311() {
21949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21950         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21951         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21952                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21953         remote_mds_nodsh && skip "remote MDS with nodsh"
21954
21955         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21956         local mdts=$(comma_list $(mdts_nodes))
21957
21958         mkdir -p $DIR/$tdir
21959         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21960         createmany -o $DIR/$tdir/$tfile. 1000
21961
21962         # statfs data is not real time, let's just calculate it
21963         old_iused=$((old_iused + 1000))
21964
21965         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21966                         osp.*OST0000*MDT0000.create_count")
21967         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21968                                 osp.*OST0000*MDT0000.max_create_count")
21969         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21970
21971         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21972         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21973         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21974
21975         unlinkmany $DIR/$tdir/$tfile. 1000
21976
21977         do_nodes $mdts "$LCTL set_param -n \
21978                         osp.*OST0000*.max_create_count=$max_count"
21979         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21980                 do_nodes $mdts "$LCTL set_param -n \
21981                                 osp.*OST0000*.create_count=$count"
21982         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21983                         grep "=0" && error "create_count is zero"
21984
21985         local new_iused
21986         for i in $(seq 120); do
21987                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21988                 # system may be too busy to destroy all objs in time, use
21989                 # a somewhat small value to not fail autotest
21990                 [ $((old_iused - new_iused)) -gt 400 ] && break
21991                 sleep 1
21992         done
21993
21994         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21995         [ $((old_iused - new_iused)) -gt 400 ] ||
21996                 error "objs not destroyed after unlink"
21997 }
21998 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21999
22000 zfs_oid_to_objid()
22001 {
22002         local ost=$1
22003         local objid=$2
22004
22005         local vdevdir=$(dirname $(facet_vdevice $ost))
22006         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22007         local zfs_zapid=$(do_facet $ost $cmd |
22008                           grep -w "/O/0/d$((objid%32))" -C 5 |
22009                           awk '/Object/{getline; print $1}')
22010         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22011                           awk "/$objid = /"'{printf $3}')
22012
22013         echo $zfs_objid
22014 }
22015
22016 zfs_object_blksz() {
22017         local ost=$1
22018         local objid=$2
22019
22020         local vdevdir=$(dirname $(facet_vdevice $ost))
22021         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22022         local blksz=$(do_facet $ost $cmd $objid |
22023                       awk '/dblk/{getline; printf $4}')
22024
22025         case "${blksz: -1}" in
22026                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22027                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22028                 *) ;;
22029         esac
22030
22031         echo $blksz
22032 }
22033
22034 test_312() { # LU-4856
22035         remote_ost_nodsh && skip "remote OST with nodsh"
22036         [ "$ost1_FSTYPE" = "zfs" ] ||
22037                 skip_env "the test only applies to zfs"
22038
22039         local max_blksz=$(do_facet ost1 \
22040                           $ZFS get -p recordsize $(facet_device ost1) |
22041                           awk '!/VALUE/{print $3}')
22042
22043         # to make life a little bit easier
22044         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22045         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22046
22047         local tf=$DIR/$tdir/$tfile
22048         touch $tf
22049         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22050
22051         # Get ZFS object id
22052         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22053         # block size change by sequential overwrite
22054         local bs
22055
22056         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22057                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22058
22059                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22060                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22061         done
22062         rm -f $tf
22063
22064         # block size change by sequential append write
22065         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22066         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22067         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22068         local count
22069
22070         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22071                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22072                         oflag=sync conv=notrunc
22073
22074                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22075                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22076                         error "blksz error, actual $blksz, " \
22077                                 "expected: 2 * $count * $PAGE_SIZE"
22078         done
22079         rm -f $tf
22080
22081         # random write
22082         touch $tf
22083         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22084         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22085
22086         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22087         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22088         [ $blksz -eq $PAGE_SIZE ] ||
22089                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22090
22091         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22092         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22093         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22094
22095         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22096         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22097         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22098 }
22099 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22100
22101 test_313() {
22102         remote_ost_nodsh && skip "remote OST with nodsh"
22103
22104         local file=$DIR/$tfile
22105
22106         rm -f $file
22107         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22108
22109         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22110         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22111         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22112                 error "write should failed"
22113         do_facet ost1 "$LCTL set_param fail_loc=0"
22114         rm -f $file
22115 }
22116 run_test 313 "io should fail after last_rcvd update fail"
22117
22118 test_314() {
22119         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22120
22121         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22122         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22123         rm -f $DIR/$tfile
22124         wait_delete_completed
22125         do_facet ost1 "$LCTL set_param fail_loc=0"
22126 }
22127 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22128
22129 test_315() { # LU-618
22130         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22131
22132         local file=$DIR/$tfile
22133         rm -f $file
22134
22135         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22136                 error "multiop file write failed"
22137         $MULTIOP $file oO_RDONLY:r4063232_c &
22138         PID=$!
22139
22140         sleep 2
22141
22142         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22143         kill -USR1 $PID
22144
22145         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22146         rm -f $file
22147 }
22148 run_test 315 "read should be accounted"
22149
22150 test_316() {
22151         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22152         large_xattr_enabled || skip_env "ea_inode feature disabled"
22153
22154         rm -rf $DIR/$tdir/d
22155         mkdir -p $DIR/$tdir/d
22156         chown nobody $DIR/$tdir/d
22157         touch $DIR/$tdir/d/file
22158
22159         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22160 }
22161 run_test 316 "lfs mv"
22162
22163 test_317() {
22164         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22165                 skip "Need MDS version at least 2.11.53"
22166         if [ "$ost1_FSTYPE" == "zfs" ]; then
22167                 skip "LU-10370: no implementation for ZFS"
22168         fi
22169
22170         local trunc_sz
22171         local grant_blk_size
22172
22173         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22174                         awk '/grant_block_size:/ { print $2; exit; }')
22175         #
22176         # Create File of size 5M. Truncate it to below size's and verify
22177         # blocks count.
22178         #
22179         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22180                 error "Create file $DIR/$tfile failed"
22181         stack_trap "rm -f $DIR/$tfile" EXIT
22182
22183         for trunc_sz in 2097152 4097 4000 509 0; do
22184                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22185                         error "truncate $tfile to $trunc_sz failed"
22186                 local sz=$(stat --format=%s $DIR/$tfile)
22187                 local blk=$(stat --format=%b $DIR/$tfile)
22188                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22189                                      grant_blk_size) * 8))
22190
22191                 if [[ $blk -ne $trunc_blk ]]; then
22192                         $(which stat) $DIR/$tfile
22193                         error "Expected Block $trunc_blk got $blk for $tfile"
22194                 fi
22195
22196                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22197                         error "Expected Size $trunc_sz got $sz for $tfile"
22198         done
22199
22200         #
22201         # sparse file test
22202         # Create file with a hole and write actual two blocks. Block count
22203         # must be 16.
22204         #
22205         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22206                 conv=fsync || error "Create file : $DIR/$tfile"
22207
22208         # Calculate the final truncate size.
22209         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22210
22211         #
22212         # truncate to size $trunc_sz bytes. Strip the last block
22213         # The block count must drop to 8
22214         #
22215         $TRUNCATE $DIR/$tfile $trunc_sz ||
22216                 error "truncate $tfile to $trunc_sz failed"
22217
22218         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22219         sz=$(stat --format=%s $DIR/$tfile)
22220         blk=$(stat --format=%b $DIR/$tfile)
22221
22222         if [[ $blk -ne $trunc_bsz ]]; then
22223                 $(which stat) $DIR/$tfile
22224                 error "Expected Block $trunc_bsz got $blk for $tfile"
22225         fi
22226
22227         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22228                 error "Expected Size $trunc_sz got $sz for $tfile"
22229 }
22230 run_test 317 "Verify blocks get correctly update after truncate"
22231
22232 test_318() {
22233         local old_max_active=$($LCTL get_param -n \
22234                             llite.*.max_read_ahead_async_active 2>/dev/null)
22235
22236         $LCTL set_param llite.*.max_read_ahead_async_active=256
22237         local max_active=$($LCTL get_param -n \
22238                            llite.*.max_read_ahead_async_active 2>/dev/null)
22239         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22240
22241         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22242                 error "set max_read_ahead_async_active should succeed"
22243
22244         $LCTL set_param llite.*.max_read_ahead_async_active=512
22245         max_active=$($LCTL get_param -n \
22246                      llite.*.max_read_ahead_async_active 2>/dev/null)
22247         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22248
22249         # restore @max_active
22250         [ $old_max_active -ne 0 ] && $LCTL set_param \
22251                 llite.*.max_read_ahead_async_active=$old_max_active
22252
22253         local old_threshold=$($LCTL get_param -n \
22254                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22255         local max_per_file_mb=$($LCTL get_param -n \
22256                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22257
22258         local invalid=$(($max_per_file_mb + 1))
22259         $LCTL set_param \
22260                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22261                         && error "set $invalid should fail"
22262
22263         local valid=$(($invalid - 1))
22264         $LCTL set_param \
22265                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22266                         error "set $valid should succeed"
22267         local threshold=$($LCTL get_param -n \
22268                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22269         [ $threshold -eq $valid ] || error \
22270                 "expect threshold $valid got $threshold"
22271         $LCTL set_param \
22272                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22273 }
22274 run_test 318 "Verify async readahead tunables"
22275
22276 test_319() {
22277         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22278
22279         local before=$(date +%s)
22280         local evict
22281         local mdir=$DIR/$tdir
22282         local file=$mdir/xxx
22283
22284         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22285         touch $file
22286
22287 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22288         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22289         $LFS mv -m1 $file &
22290
22291         sleep 1
22292         dd if=$file of=/dev/null
22293         wait
22294         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22295           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22296
22297         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22298 }
22299 run_test 319 "lost lease lock on migrate error"
22300
22301 test_398a() { # LU-4198
22302         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22303         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22304
22305         # request a new lock on client
22306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22307
22308         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22309         local lock_count=$($LCTL get_param -n \
22310                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22311         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22312
22313         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22314
22315         # no lock cached, should use lockless IO and not enqueue new lock
22316         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22317         lock_count=$($LCTL get_param -n \
22318                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22319         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22320 }
22321 run_test 398a "direct IO should cancel lock otherwise lockless"
22322
22323 test_398b() { # LU-4198
22324         which fio || skip_env "no fio installed"
22325         $LFS setstripe -c -1 $DIR/$tfile
22326
22327         local size=12
22328         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22329
22330         local njobs=4
22331         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22332         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22333                 --numjobs=$njobs --fallocate=none \
22334                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22335                 --filename=$DIR/$tfile &
22336         bg_pid=$!
22337
22338         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22339         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22340                 --numjobs=$njobs --fallocate=none \
22341                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22342                 --filename=$DIR/$tfile || true
22343         wait $bg_pid
22344
22345         rm -rf $DIR/$tfile
22346 }
22347 run_test 398b "DIO and buffer IO race"
22348
22349 test_398c() { # LU-4198
22350         which fio || skip_env "no fio installed"
22351
22352         saved_debug=$($LCTL get_param -n debug)
22353         $LCTL set_param debug=0
22354
22355         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22356         ((size /= 1024)) # by megabytes
22357         ((size /= 2)) # write half of the OST at most
22358         [ $size -gt 40 ] && size=40 #reduce test time anyway
22359
22360         $LFS setstripe -c 1 $DIR/$tfile
22361
22362         # it seems like ldiskfs reserves more space than necessary if the
22363         # writing blocks are not mapped, so it extends the file firstly
22364         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22365         cancel_lru_locks osc
22366
22367         # clear and verify rpc_stats later
22368         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22369
22370         local njobs=4
22371         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22372         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22373                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22374                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22375                 --filename=$DIR/$tfile
22376         [ $? -eq 0 ] || error "fio write error"
22377
22378         [ $($LCTL get_param -n \
22379          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22380                 error "Locks were requested while doing AIO"
22381
22382         # get the percentage of 1-page I/O
22383         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22384                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22385                 awk '{print $7}')
22386         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22387
22388         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22389         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22390                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22391                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22392                 --filename=$DIR/$tfile
22393         [ $? -eq 0 ] || error "fio mixed read write error"
22394
22395         echo "AIO with large block size ${size}M"
22396         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22397                 --numjobs=1 --fallocate=none --ioengine=libaio \
22398                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22399                 --filename=$DIR/$tfile
22400         [ $? -eq 0 ] || error "fio large block size failed"
22401
22402         rm -rf $DIR/$tfile
22403         $LCTL set_param debug="$saved_debug"
22404 }
22405 run_test 398c "run fio to test AIO"
22406
22407 test_398d() { #  LU-13846
22408         test -f aiocp || skip_env "no aiocp installed"
22409         local aio_file=$DIR/aio_file
22410
22411         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22412
22413         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22414         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22415
22416         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22417
22418         # make sure we don't crash and fail properly
22419         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22420                 error "aio not aligned with PAGE SIZE should fail"
22421
22422         rm -rf $DIR/$tfile $aio_file
22423 }
22424 run_test 398d "run aiocp to verify block size > stripe size"
22425
22426 test_398e() {
22427         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22428         touch $DIR/$tfile.new
22429         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22430 }
22431 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22432
22433 test_fake_rw() {
22434         local read_write=$1
22435         if [ "$read_write" = "write" ]; then
22436                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22437         elif [ "$read_write" = "read" ]; then
22438                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22439         else
22440                 error "argument error"
22441         fi
22442
22443         # turn off debug for performance testing
22444         local saved_debug=$($LCTL get_param -n debug)
22445         $LCTL set_param debug=0
22446
22447         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22448
22449         # get ost1 size - $FSNAME-OST0000
22450         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22451         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22452         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22453
22454         if [ "$read_write" = "read" ]; then
22455                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22456         fi
22457
22458         local start_time=$(date +%s.%N)
22459         $dd_cmd bs=1M count=$blocks oflag=sync ||
22460                 error "real dd $read_write error"
22461         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22462
22463         if [ "$read_write" = "write" ]; then
22464                 rm -f $DIR/$tfile
22465         fi
22466
22467         # define OBD_FAIL_OST_FAKE_RW           0x238
22468         do_facet ost1 $LCTL set_param fail_loc=0x238
22469
22470         local start_time=$(date +%s.%N)
22471         $dd_cmd bs=1M count=$blocks oflag=sync ||
22472                 error "fake dd $read_write error"
22473         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22474
22475         if [ "$read_write" = "write" ]; then
22476                 # verify file size
22477                 cancel_lru_locks osc
22478                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22479                         error "$tfile size not $blocks MB"
22480         fi
22481         do_facet ost1 $LCTL set_param fail_loc=0
22482
22483         echo "fake $read_write $duration_fake vs. normal $read_write" \
22484                 "$duration in seconds"
22485         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22486                 error_not_in_vm "fake write is slower"
22487
22488         $LCTL set_param -n debug="$saved_debug"
22489         rm -f $DIR/$tfile
22490 }
22491 test_399a() { # LU-7655 for OST fake write
22492         remote_ost_nodsh && skip "remote OST with nodsh"
22493
22494         test_fake_rw write
22495 }
22496 run_test 399a "fake write should not be slower than normal write"
22497
22498 test_399b() { # LU-8726 for OST fake read
22499         remote_ost_nodsh && skip "remote OST with nodsh"
22500         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22501                 skip_env "ldiskfs only test"
22502         fi
22503
22504         test_fake_rw read
22505 }
22506 run_test 399b "fake read should not be slower than normal read"
22507
22508 test_400a() { # LU-1606, was conf-sanity test_74
22509         if ! which $CC > /dev/null 2>&1; then
22510                 skip_env "$CC is not installed"
22511         fi
22512
22513         local extra_flags=''
22514         local out=$TMP/$tfile
22515         local prefix=/usr/include/lustre
22516         local prog
22517
22518         # Oleg removes c files in his test rig so test if any c files exist
22519         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22520                 skip_env "Needed c test files are missing"
22521
22522         if ! [[ -d $prefix ]]; then
22523                 # Assume we're running in tree and fixup the include path.
22524                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22525                 extra_flags+=" -L$LUSTRE/utils/.lib"
22526         fi
22527
22528         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22529                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22530                         error "client api broken"
22531         done
22532         rm -f $out
22533 }
22534 run_test 400a "Lustre client api program can compile and link"
22535
22536 test_400b() { # LU-1606, LU-5011
22537         local header
22538         local out=$TMP/$tfile
22539         local prefix=/usr/include/linux/lustre
22540
22541         # We use a hard coded prefix so that this test will not fail
22542         # when run in tree. There are headers in lustre/include/lustre/
22543         # that are not packaged (like lustre_idl.h) and have more
22544         # complicated include dependencies (like config.h and lnet/types.h).
22545         # Since this test about correct packaging we just skip them when
22546         # they don't exist (see below) rather than try to fixup cppflags.
22547
22548         if ! which $CC > /dev/null 2>&1; then
22549                 skip_env "$CC is not installed"
22550         fi
22551
22552         for header in $prefix/*.h; do
22553                 if ! [[ -f "$header" ]]; then
22554                         continue
22555                 fi
22556
22557                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22558                         continue # lustre_ioctl.h is internal header
22559                 fi
22560
22561                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22562                         error "cannot compile '$header'"
22563         done
22564         rm -f $out
22565 }
22566 run_test 400b "packaged headers can be compiled"
22567
22568 test_401a() { #LU-7437
22569         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22570         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22571
22572         #count the number of parameters by "list_param -R"
22573         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22574         #count the number of parameters by listing proc files
22575         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22576         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22577         echo "proc_dirs='$proc_dirs'"
22578         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22579         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22580                       sort -u | wc -l)
22581
22582         [ $params -eq $procs ] ||
22583                 error "found $params parameters vs. $procs proc files"
22584
22585         # test the list_param -D option only returns directories
22586         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22587         #count the number of parameters by listing proc directories
22588         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22589                 sort -u | wc -l)
22590
22591         [ $params -eq $procs ] ||
22592                 error "found $params parameters vs. $procs proc files"
22593 }
22594 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22595
22596 test_401b() {
22597         # jobid_var may not allow arbitrary values, so use jobid_name
22598         # if available
22599         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22600                 local testname=jobid_name tmp='testing%p'
22601         else
22602                 local testname=jobid_var tmp=testing
22603         fi
22604
22605         local save=$($LCTL get_param -n $testname)
22606
22607         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22608                 error "no error returned when setting bad parameters"
22609
22610         local jobid_new=$($LCTL get_param -n foe $testname baz)
22611         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22612
22613         $LCTL set_param -n fog=bam $testname=$save bat=fog
22614         local jobid_old=$($LCTL get_param -n foe $testname bag)
22615         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22616 }
22617 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22618
22619 test_401c() {
22620         # jobid_var may not allow arbitrary values, so use jobid_name
22621         # if available
22622         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22623                 local testname=jobid_name
22624         else
22625                 local testname=jobid_var
22626         fi
22627
22628         local jobid_var_old=$($LCTL get_param -n $testname)
22629         local jobid_var_new
22630
22631         $LCTL set_param $testname= &&
22632                 error "no error returned for 'set_param a='"
22633
22634         jobid_var_new=$($LCTL get_param -n $testname)
22635         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22636                 error "$testname was changed by setting without value"
22637
22638         $LCTL set_param $testname &&
22639                 error "no error returned for 'set_param a'"
22640
22641         jobid_var_new=$($LCTL get_param -n $testname)
22642         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22643                 error "$testname was changed by setting without value"
22644 }
22645 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22646
22647 test_401d() {
22648         # jobid_var may not allow arbitrary values, so use jobid_name
22649         # if available
22650         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22651                 local testname=jobid_name new_value='foo=bar%p'
22652         else
22653                 local testname=jobid_var new_valuie=foo=bar
22654         fi
22655
22656         local jobid_var_old=$($LCTL get_param -n $testname)
22657         local jobid_var_new
22658
22659         $LCTL set_param $testname=$new_value ||
22660                 error "'set_param a=b' did not accept a value containing '='"
22661
22662         jobid_var_new=$($LCTL get_param -n $testname)
22663         [[ "$jobid_var_new" == "$new_value" ]] ||
22664                 error "'set_param a=b' failed on a value containing '='"
22665
22666         # Reset the $testname to test the other format
22667         $LCTL set_param $testname=$jobid_var_old
22668         jobid_var_new=$($LCTL get_param -n $testname)
22669         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22670                 error "failed to reset $testname"
22671
22672         $LCTL set_param $testname $new_value ||
22673                 error "'set_param a b' did not accept a value containing '='"
22674
22675         jobid_var_new=$($LCTL get_param -n $testname)
22676         [[ "$jobid_var_new" == "$new_value" ]] ||
22677                 error "'set_param a b' failed on a value containing '='"
22678
22679         $LCTL set_param $testname $jobid_var_old
22680         jobid_var_new=$($LCTL get_param -n $testname)
22681         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22682                 error "failed to reset $testname"
22683 }
22684 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22685
22686 test_402() {
22687         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22688         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22689                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22690         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22691                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22692                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22693         remote_mds_nodsh && skip "remote MDS with nodsh"
22694
22695         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22696 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22697         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22698         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22699                 echo "Touch failed - OK"
22700 }
22701 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22702
22703 test_403() {
22704         local file1=$DIR/$tfile.1
22705         local file2=$DIR/$tfile.2
22706         local tfile=$TMP/$tfile
22707
22708         rm -f $file1 $file2 $tfile
22709
22710         touch $file1
22711         ln $file1 $file2
22712
22713         # 30 sec OBD_TIMEOUT in ll_getattr()
22714         # right before populating st_nlink
22715         $LCTL set_param fail_loc=0x80001409
22716         stat -c %h $file1 > $tfile &
22717
22718         # create an alias, drop all locks and reclaim the dentry
22719         < $file2
22720         cancel_lru_locks mdc
22721         cancel_lru_locks osc
22722         sysctl -w vm.drop_caches=2
22723
22724         wait
22725
22726         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22727
22728         rm -f $tfile $file1 $file2
22729 }
22730 run_test 403 "i_nlink should not drop to zero due to aliasing"
22731
22732 test_404() { # LU-6601
22733         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22734                 skip "Need server version newer than 2.8.52"
22735         remote_mds_nodsh && skip "remote MDS with nodsh"
22736
22737         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22738                 awk '/osp .*-osc-MDT/ { print $4}')
22739
22740         local osp
22741         for osp in $mosps; do
22742                 echo "Deactivate: " $osp
22743                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22744                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22745                         awk -vp=$osp '$4 == p { print $2 }')
22746                 [ $stat = IN ] || {
22747                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22748                         error "deactivate error"
22749                 }
22750                 echo "Activate: " $osp
22751                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22752                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22753                         awk -vp=$osp '$4 == p { print $2 }')
22754                 [ $stat = UP ] || {
22755                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22756                         error "activate error"
22757                 }
22758         done
22759 }
22760 run_test 404 "validate manual {de}activated works properly for OSPs"
22761
22762 test_405() {
22763         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22764         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22765                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22766                         skip "Layout swap lock is not supported"
22767
22768         check_swap_layouts_support
22769         check_swap_layout_no_dom $DIR
22770
22771         test_mkdir $DIR/$tdir
22772         swap_lock_test -d $DIR/$tdir ||
22773                 error "One layout swap locked test failed"
22774 }
22775 run_test 405 "Various layout swap lock tests"
22776
22777 test_406() {
22778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22779         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22780         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22782         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22783                 skip "Need MDS version at least 2.8.50"
22784
22785         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22786         local test_pool=$TESTNAME
22787
22788         pool_add $test_pool || error "pool_add failed"
22789         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22790                 error "pool_add_targets failed"
22791
22792         save_layout_restore_at_exit $MOUNT
22793
22794         # parent set default stripe count only, child will stripe from both
22795         # parent and fs default
22796         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22797                 error "setstripe $MOUNT failed"
22798         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22799         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22800         for i in $(seq 10); do
22801                 local f=$DIR/$tdir/$tfile.$i
22802                 touch $f || error "touch failed"
22803                 local count=$($LFS getstripe -c $f)
22804                 [ $count -eq $OSTCOUNT ] ||
22805                         error "$f stripe count $count != $OSTCOUNT"
22806                 local offset=$($LFS getstripe -i $f)
22807                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22808                 local size=$($LFS getstripe -S $f)
22809                 [ $size -eq $((def_stripe_size * 2)) ] ||
22810                         error "$f stripe size $size != $((def_stripe_size * 2))"
22811                 local pool=$($LFS getstripe -p $f)
22812                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22813         done
22814
22815         # change fs default striping, delete parent default striping, now child
22816         # will stripe from new fs default striping only
22817         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22818                 error "change $MOUNT default stripe failed"
22819         $LFS setstripe -c 0 $DIR/$tdir ||
22820                 error "delete $tdir default stripe failed"
22821         for i in $(seq 11 20); do
22822                 local f=$DIR/$tdir/$tfile.$i
22823                 touch $f || error "touch $f failed"
22824                 local count=$($LFS getstripe -c $f)
22825                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22826                 local offset=$($LFS getstripe -i $f)
22827                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22828                 local size=$($LFS getstripe -S $f)
22829                 [ $size -eq $def_stripe_size ] ||
22830                         error "$f stripe size $size != $def_stripe_size"
22831                 local pool=$($LFS getstripe -p $f)
22832                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22833         done
22834
22835         unlinkmany $DIR/$tdir/$tfile. 1 20
22836
22837         local f=$DIR/$tdir/$tfile
22838         pool_remove_all_targets $test_pool $f
22839         pool_remove $test_pool $f
22840 }
22841 run_test 406 "DNE support fs default striping"
22842
22843 test_407() {
22844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22845         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22846                 skip "Need MDS version at least 2.8.55"
22847         remote_mds_nodsh && skip "remote MDS with nodsh"
22848
22849         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22850                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22851         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22852                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22853         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22854
22855         #define OBD_FAIL_DT_TXN_STOP    0x2019
22856         for idx in $(seq $MDSCOUNT); do
22857                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22858         done
22859         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22860         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22861                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22862         true
22863 }
22864 run_test 407 "transaction fail should cause operation fail"
22865
22866 test_408() {
22867         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22868
22869         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22870         lctl set_param fail_loc=0x8000040a
22871         # let ll_prepare_partial_page() fail
22872         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22873
22874         rm -f $DIR/$tfile
22875
22876         # create at least 100 unused inodes so that
22877         # shrink_icache_memory(0) should not return 0
22878         touch $DIR/$tfile-{0..100}
22879         rm -f $DIR/$tfile-{0..100}
22880         sync
22881
22882         echo 2 > /proc/sys/vm/drop_caches
22883 }
22884 run_test 408 "drop_caches should not hang due to page leaks"
22885
22886 test_409()
22887 {
22888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22889
22890         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22891         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22892         touch $DIR/$tdir/guard || error "(2) Fail to create"
22893
22894         local PREFIX=$(str_repeat 'A' 128)
22895         echo "Create 1K hard links start at $(date)"
22896         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22897                 error "(3) Fail to hard link"
22898
22899         echo "Links count should be right although linkEA overflow"
22900         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22901         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22902         [ $linkcount -eq 1001 ] ||
22903                 error "(5) Unexpected hard links count: $linkcount"
22904
22905         echo "List all links start at $(date)"
22906         ls -l $DIR/$tdir/foo > /dev/null ||
22907                 error "(6) Fail to list $DIR/$tdir/foo"
22908
22909         echo "Unlink hard links start at $(date)"
22910         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22911                 error "(7) Fail to unlink"
22912         echo "Unlink hard links finished at $(date)"
22913 }
22914 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22915
22916 test_410()
22917 {
22918         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22919                 skip "Need client version at least 2.9.59"
22920         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22921                 skip "Need MODULES build"
22922
22923         # Create a file, and stat it from the kernel
22924         local testfile=$DIR/$tfile
22925         touch $testfile
22926
22927         local run_id=$RANDOM
22928         local my_ino=$(stat --format "%i" $testfile)
22929
22930         # Try to insert the module. This will always fail as the
22931         # module is designed to not be inserted.
22932         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22933             &> /dev/null
22934
22935         # Anything but success is a test failure
22936         dmesg | grep -q \
22937             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22938             error "no inode match"
22939 }
22940 run_test 410 "Test inode number returned from kernel thread"
22941
22942 cleanup_test411_cgroup() {
22943         trap 0
22944         rmdir "$1"
22945 }
22946
22947 test_411() {
22948         local cg_basedir=/sys/fs/cgroup/memory
22949         # LU-9966
22950         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22951                 skip "no setup for cgroup"
22952
22953         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22954                 error "test file creation failed"
22955         cancel_lru_locks osc
22956
22957         # Create a very small memory cgroup to force a slab allocation error
22958         local cgdir=$cg_basedir/osc_slab_alloc
22959         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22960         trap "cleanup_test411_cgroup $cgdir" EXIT
22961         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22962         echo 1M > $cgdir/memory.limit_in_bytes
22963
22964         # Should not LBUG, just be killed by oom-killer
22965         # dd will return 0 even allocation failure in some environment.
22966         # So don't check return value
22967         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22968         cleanup_test411_cgroup $cgdir
22969
22970         return 0
22971 }
22972 run_test 411 "Slab allocation error with cgroup does not LBUG"
22973
22974 test_412() {
22975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22976         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22977                 skip "Need server version at least 2.10.55"
22978         fi
22979
22980         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22981                 error "mkdir failed"
22982         $LFS getdirstripe $DIR/$tdir
22983         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22984         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22985                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22986         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22987         [ $stripe_count -eq 2 ] ||
22988                 error "expect 2 get $stripe_count"
22989 }
22990 run_test 412 "mkdir on specific MDTs"
22991
22992 test_qos_mkdir() {
22993         local mkdir_cmd=$1
22994         local stripe_count=$2
22995         local mdts=$(comma_list $(mdts_nodes))
22996
22997         local testdir
22998         local lmv_qos_prio_free
22999         local lmv_qos_threshold_rr
23000         local lmv_qos_maxage
23001         local lod_qos_prio_free
23002         local lod_qos_threshold_rr
23003         local lod_qos_maxage
23004         local count
23005         local i
23006
23007         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23008         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23009         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23010                 head -n1)
23011         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23012         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23013         stack_trap "$LCTL set_param \
23014                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23015         stack_trap "$LCTL set_param \
23016                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23017         stack_trap "$LCTL set_param \
23018                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23019
23020         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23021                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23022         lod_qos_prio_free=${lod_qos_prio_free%%%}
23023         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23024                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23025         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23026         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23027                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23028         stack_trap "do_nodes $mdts $LCTL set_param \
23029                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23030         stack_trap "do_nodes $mdts $LCTL set_param \
23031                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23032                 EXIT
23033         stack_trap "do_nodes $mdts $LCTL set_param \
23034                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23035
23036         echo
23037         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23038
23039         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23040         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23041
23042         testdir=$DIR/$tdir-s$stripe_count/rr
23043
23044         for i in $(seq $((100 * MDSCOUNT))); do
23045                 eval $mkdir_cmd $testdir/subdir$i ||
23046                         error "$mkdir_cmd subdir$i failed"
23047         done
23048
23049         for i in $(seq $MDSCOUNT); do
23050                 count=$($LFS getdirstripe -i $testdir/* |
23051                                 grep ^$((i - 1))$ | wc -l)
23052                 echo "$count directories created on MDT$((i - 1))"
23053                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23054
23055                 if [ $stripe_count -gt 1 ]; then
23056                         count=$($LFS getdirstripe $testdir/* |
23057                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23058                         echo "$count stripes created on MDT$((i - 1))"
23059                         # deviation should < 5% of average
23060                         [ $count -lt $((95 * stripe_count)) ] ||
23061                         [ $count -gt $((105 * stripe_count)) ] &&
23062                                 error "stripes are not evenly distributed"
23063                 fi
23064         done
23065
23066         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23067         do_nodes $mdts $LCTL set_param \
23068                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23069
23070         echo
23071         echo "Check for uneven MDTs: "
23072
23073         local ffree
23074         local bavail
23075         local max
23076         local min
23077         local max_index
23078         local min_index
23079         local tmp
23080
23081         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23082         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23083         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23084
23085         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23086         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23087         max_index=0
23088         min_index=0
23089         for ((i = 1; i < ${#ffree[@]}; i++)); do
23090                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23091                 if [ $tmp -gt $max ]; then
23092                         max=$tmp
23093                         max_index=$i
23094                 fi
23095                 if [ $tmp -lt $min ]; then
23096                         min=$tmp
23097                         min_index=$i
23098                 fi
23099         done
23100
23101         [ ${ffree[min_index]} -eq 0 ] &&
23102                 skip "no free files in MDT$min_index"
23103         [ ${ffree[min_index]} -gt 100000000 ] &&
23104                 skip "too much free files in MDT$min_index"
23105
23106         # Check if we need to generate uneven MDTs
23107         local threshold=50
23108         local diff=$(((max - min) * 100 / min))
23109         local value="$(generate_string 1024)"
23110
23111         while [ $diff -lt $threshold ]; do
23112                 # generate uneven MDTs, create till $threshold% diff
23113                 echo -n "weight diff=$diff% must be > $threshold% ..."
23114                 count=$((${ffree[min_index]} / 10))
23115                 # 50 sec per 10000 files in vm
23116                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23117                         skip "$count files to create"
23118                 echo "Fill MDT$min_index with $count files"
23119                 [ -d $DIR/$tdir-MDT$min_index ] ||
23120                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23121                         error "mkdir $tdir-MDT$min_index failed"
23122                 for i in $(seq $count); do
23123                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23124                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23125                                 error "create f$j_$i failed"
23126                         setfattr -n user.413b -v $value \
23127                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23128                                 error "setfattr f$j_$i failed"
23129                 done
23130
23131                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23132                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23133                 max=$(((${ffree[max_index]} >> 8) * \
23134                         (${bavail[max_index]} * bsize >> 16)))
23135                 min=$(((${ffree[min_index]} >> 8) * \
23136                         (${bavail[min_index]} * bsize >> 16)))
23137                 diff=$(((max - min) * 100 / min))
23138         done
23139
23140         echo "MDT filesfree available: ${ffree[@]}"
23141         echo "MDT blocks available: ${bavail[@]}"
23142         echo "weight diff=$diff%"
23143
23144         echo
23145         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23146
23147         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23148         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23149         # decrease statfs age, so that it can be updated in time
23150         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23151         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23152
23153         sleep 1
23154
23155         testdir=$DIR/$tdir-s$stripe_count/qos
23156
23157         for i in $(seq $((100 * MDSCOUNT))); do
23158                 eval $mkdir_cmd $testdir/subdir$i ||
23159                         error "$mkdir_cmd subdir$i failed"
23160         done
23161
23162         for i in $(seq $MDSCOUNT); do
23163                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23164                         wc -l)
23165                 echo "$count directories created on MDT$((i - 1))"
23166
23167                 if [ $stripe_count -gt 1 ]; then
23168                         count=$($LFS getdirstripe $testdir/* |
23169                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23170                         echo "$count stripes created on MDT$((i - 1))"
23171                 fi
23172         done
23173
23174         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23175         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23176
23177         # D-value should > 10% of averge
23178         [ $((max - min)) -lt 10 ] &&
23179                 error "subdirs shouldn't be evenly distributed"
23180
23181         # ditto
23182         if [ $stripe_count -gt 1 ]; then
23183                 max=$($LFS getdirstripe $testdir/* |
23184                         grep -P "^\s+$max_index\t" | wc -l)
23185                 min=$($LFS getdirstripe $testdir/* |
23186                         grep -P "^\s+$min_index\t" | wc -l)
23187                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23188                         error "stripes shouldn't be evenly distributed"|| true
23189         fi
23190 }
23191
23192 test_413a() {
23193         [ $MDSCOUNT -lt 2 ] &&
23194                 skip "We need at least 2 MDTs for this test"
23195
23196         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23197                 skip "Need server version at least 2.12.52"
23198
23199         local stripe_count
23200
23201         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23202                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23203                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23204                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23205                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23206         done
23207 }
23208 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23209
23210 test_413b() {
23211         [ $MDSCOUNT -lt 2 ] &&
23212                 skip "We need at least 2 MDTs for this test"
23213
23214         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23215                 skip "Need server version at least 2.12.52"
23216
23217         local stripe_count
23218
23219         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23220                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23221                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23222                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23223                 $LFS setdirstripe -D -c $stripe_count \
23224                         $DIR/$tdir-s$stripe_count/rr ||
23225                         error "setdirstripe failed"
23226                 $LFS setdirstripe -D -c $stripe_count \
23227                         $DIR/$tdir-s$stripe_count/qos ||
23228                         error "setdirstripe failed"
23229                 test_qos_mkdir "mkdir" $stripe_count
23230         done
23231 }
23232 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23233
23234 test_414() {
23235 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23236         $LCTL set_param fail_loc=0x80000521
23237         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23238         rm -f $DIR/$tfile
23239 }
23240 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23241
23242 test_415() {
23243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23244         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23245                 skip "Need server version at least 2.11.52"
23246
23247         # LU-11102
23248         local total
23249         local setattr_pid
23250         local start_time
23251         local end_time
23252         local duration
23253
23254         total=500
23255         # this test may be slow on ZFS
23256         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23257
23258         # though this test is designed for striped directory, let's test normal
23259         # directory too since lock is always saved as CoS lock.
23260         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23261         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23262
23263         (
23264                 while true; do
23265                         touch $DIR/$tdir
23266                 done
23267         ) &
23268         setattr_pid=$!
23269
23270         start_time=$(date +%s)
23271         for i in $(seq $total); do
23272                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23273                         > /dev/null
23274         done
23275         end_time=$(date +%s)
23276         duration=$((end_time - start_time))
23277
23278         kill -9 $setattr_pid
23279
23280         echo "rename $total files took $duration sec"
23281         [ $duration -lt 100 ] || error "rename took $duration sec"
23282 }
23283 run_test 415 "lock revoke is not missing"
23284
23285 test_416() {
23286         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23287                 skip "Need server version at least 2.11.55"
23288
23289         # define OBD_FAIL_OSD_TXN_START    0x19a
23290         do_facet mds1 lctl set_param fail_loc=0x19a
23291
23292         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23293
23294         true
23295 }
23296 run_test 416 "transaction start failure won't cause system hung"
23297
23298 cleanup_417() {
23299         trap 0
23300         do_nodes $(comma_list $(mdts_nodes)) \
23301                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23302         do_nodes $(comma_list $(mdts_nodes)) \
23303                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23304         do_nodes $(comma_list $(mdts_nodes)) \
23305                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23306 }
23307
23308 test_417() {
23309         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23310         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23311                 skip "Need MDS version at least 2.11.56"
23312
23313         trap cleanup_417 RETURN EXIT
23314
23315         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23316         do_nodes $(comma_list $(mdts_nodes)) \
23317                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23318         $LFS migrate -m 0 $DIR/$tdir.1 &&
23319                 error "migrate dir $tdir.1 should fail"
23320
23321         do_nodes $(comma_list $(mdts_nodes)) \
23322                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23323         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23324                 error "create remote dir $tdir.2 should fail"
23325
23326         do_nodes $(comma_list $(mdts_nodes)) \
23327                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23328         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23329                 error "create striped dir $tdir.3 should fail"
23330         true
23331 }
23332 run_test 417 "disable remote dir, striped dir and dir migration"
23333
23334 # Checks that the outputs of df [-i] and lfs df [-i] match
23335 #
23336 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23337 check_lfs_df() {
23338         local dir=$2
23339         local inodes
23340         local df_out
23341         local lfs_df_out
23342         local count
23343         local passed=false
23344
23345         # blocks or inodes
23346         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23347
23348         for count in {1..100}; do
23349                 cancel_lru_locks
23350                 sync; sleep 0.2
23351
23352                 # read the lines of interest
23353                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23354                         error "df $inodes $dir | tail -n +2 failed"
23355                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23356                         error "lfs df $inodes $dir | grep summary: failed"
23357
23358                 # skip first substrings of each output as they are different
23359                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23360                 # compare the two outputs
23361                 passed=true
23362                 for i in {1..5}; do
23363                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23364                 done
23365                 $passed && break
23366         done
23367
23368         if ! $passed; then
23369                 df -P $inodes $dir
23370                 echo
23371                 lfs df $inodes $dir
23372                 error "df and lfs df $1 output mismatch: "      \
23373                       "df ${inodes}: ${df_out[*]}, "            \
23374                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23375         fi
23376 }
23377
23378 test_418() {
23379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23380
23381         local dir=$DIR/$tdir
23382         local numfiles=$((RANDOM % 4096 + 2))
23383         local numblocks=$((RANDOM % 256 + 1))
23384
23385         wait_delete_completed
23386         test_mkdir $dir
23387
23388         # check block output
23389         check_lfs_df blocks $dir
23390         # check inode output
23391         check_lfs_df inodes $dir
23392
23393         # create a single file and retest
23394         echo "Creating a single file and testing"
23395         createmany -o $dir/$tfile- 1 &>/dev/null ||
23396                 error "creating 1 file in $dir failed"
23397         check_lfs_df blocks $dir
23398         check_lfs_df inodes $dir
23399
23400         # create a random number of files
23401         echo "Creating $((numfiles - 1)) files and testing"
23402         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23403                 error "creating $((numfiles - 1)) files in $dir failed"
23404
23405         # write a random number of blocks to the first test file
23406         echo "Writing $numblocks 4K blocks and testing"
23407         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23408                 count=$numblocks &>/dev/null ||
23409                 error "dd to $dir/${tfile}-0 failed"
23410
23411         # retest
23412         check_lfs_df blocks $dir
23413         check_lfs_df inodes $dir
23414
23415         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23416                 error "unlinking $numfiles files in $dir failed"
23417 }
23418 run_test 418 "df and lfs df outputs match"
23419
23420 test_419()
23421 {
23422         local dir=$DIR/$tdir
23423
23424         mkdir -p $dir
23425         touch $dir/file
23426
23427         cancel_lru_locks mdc
23428
23429         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23430         $LCTL set_param fail_loc=0x1410
23431         cat $dir/file
23432         $LCTL set_param fail_loc=0
23433         rm -rf $dir
23434 }
23435 run_test 419 "Verify open file by name doesn't crash kernel"
23436
23437 test_420()
23438 {
23439         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23440                 skip "Need MDS version at least 2.12.53"
23441
23442         local SAVE_UMASK=$(umask)
23443         local dir=$DIR/$tdir
23444         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23445
23446         mkdir -p $dir
23447         umask 0000
23448         mkdir -m03777 $dir/testdir
23449         ls -dn $dir/testdir
23450         # Need to remove trailing '.' when SELinux is enabled
23451         local dirperms=$(ls -dn $dir/testdir |
23452                          awk '{ sub(/\.$/, "", $1); print $1}')
23453         [ $dirperms == "drwxrwsrwt" ] ||
23454                 error "incorrect perms on $dir/testdir"
23455
23456         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23457                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23458         ls -n $dir/testdir/testfile
23459         local fileperms=$(ls -n $dir/testdir/testfile |
23460                           awk '{ sub(/\.$/, "", $1); print $1}')
23461         [ $fileperms == "-rwxr-xr-x" ] ||
23462                 error "incorrect perms on $dir/testdir/testfile"
23463
23464         umask $SAVE_UMASK
23465 }
23466 run_test 420 "clear SGID bit on non-directories for non-members"
23467
23468 test_421a() {
23469         local cnt
23470         local fid1
23471         local fid2
23472
23473         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23474                 skip "Need MDS version at least 2.12.54"
23475
23476         test_mkdir $DIR/$tdir
23477         createmany -o $DIR/$tdir/f 3
23478         cnt=$(ls -1 $DIR/$tdir | wc -l)
23479         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23480
23481         fid1=$(lfs path2fid $DIR/$tdir/f1)
23482         fid2=$(lfs path2fid $DIR/$tdir/f2)
23483         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23484
23485         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23486         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23487
23488         cnt=$(ls -1 $DIR/$tdir | wc -l)
23489         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23490
23491         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23492         createmany -o $DIR/$tdir/f 3
23493         cnt=$(ls -1 $DIR/$tdir | wc -l)
23494         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23495
23496         fid1=$(lfs path2fid $DIR/$tdir/f1)
23497         fid2=$(lfs path2fid $DIR/$tdir/f2)
23498         echo "remove using fsname $FSNAME"
23499         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23500
23501         cnt=$(ls -1 $DIR/$tdir | wc -l)
23502         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23503 }
23504 run_test 421a "simple rm by fid"
23505
23506 test_421b() {
23507         local cnt
23508         local FID1
23509         local FID2
23510
23511         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23512                 skip "Need MDS version at least 2.12.54"
23513
23514         test_mkdir $DIR/$tdir
23515         createmany -o $DIR/$tdir/f 3
23516         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23517         MULTIPID=$!
23518
23519         FID1=$(lfs path2fid $DIR/$tdir/f1)
23520         FID2=$(lfs path2fid $DIR/$tdir/f2)
23521         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23522
23523         kill -USR1 $MULTIPID
23524         wait
23525
23526         cnt=$(ls $DIR/$tdir | wc -l)
23527         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23528 }
23529 run_test 421b "rm by fid on open file"
23530
23531 test_421c() {
23532         local cnt
23533         local FIDS
23534
23535         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23536                 skip "Need MDS version at least 2.12.54"
23537
23538         test_mkdir $DIR/$tdir
23539         createmany -o $DIR/$tdir/f 3
23540         touch $DIR/$tdir/$tfile
23541         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23542         cnt=$(ls -1 $DIR/$tdir | wc -l)
23543         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23544
23545         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23546         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23547
23548         cnt=$(ls $DIR/$tdir | wc -l)
23549         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23550 }
23551 run_test 421c "rm by fid against hardlinked files"
23552
23553 test_421d() {
23554         local cnt
23555         local FIDS
23556
23557         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23558                 skip "Need MDS version at least 2.12.54"
23559
23560         test_mkdir $DIR/$tdir
23561         createmany -o $DIR/$tdir/f 4097
23562         cnt=$(ls -1 $DIR/$tdir | wc -l)
23563         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23564
23565         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23566         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23567
23568         cnt=$(ls $DIR/$tdir | wc -l)
23569         rm -rf $DIR/$tdir
23570         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23571 }
23572 run_test 421d "rmfid en masse"
23573
23574 test_421e() {
23575         local cnt
23576         local FID
23577
23578         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23579         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23580                 skip "Need MDS version at least 2.12.54"
23581
23582         mkdir -p $DIR/$tdir
23583         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23584         createmany -o $DIR/$tdir/striped_dir/f 512
23585         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23586         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23587
23588         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23589                 sed "s/[/][^:]*://g")
23590         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23591
23592         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23593         rm -rf $DIR/$tdir
23594         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23595 }
23596 run_test 421e "rmfid in DNE"
23597
23598 test_421f() {
23599         local cnt
23600         local FID
23601
23602         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23603                 skip "Need MDS version at least 2.12.54"
23604
23605         test_mkdir $DIR/$tdir
23606         touch $DIR/$tdir/f
23607         cnt=$(ls -1 $DIR/$tdir | wc -l)
23608         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23609
23610         FID=$(lfs path2fid $DIR/$tdir/f)
23611         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23612         # rmfid should fail
23613         cnt=$(ls -1 $DIR/$tdir | wc -l)
23614         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23615
23616         chmod a+rw $DIR/$tdir
23617         ls -la $DIR/$tdir
23618         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23619         # rmfid should fail
23620         cnt=$(ls -1 $DIR/$tdir | wc -l)
23621         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23622
23623         rm -f $DIR/$tdir/f
23624         $RUNAS touch $DIR/$tdir/f
23625         FID=$(lfs path2fid $DIR/$tdir/f)
23626         echo "rmfid as root"
23627         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23628         cnt=$(ls -1 $DIR/$tdir | wc -l)
23629         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23630
23631         rm -f $DIR/$tdir/f
23632         $RUNAS touch $DIR/$tdir/f
23633         cnt=$(ls -1 $DIR/$tdir | wc -l)
23634         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23635         FID=$(lfs path2fid $DIR/$tdir/f)
23636         # rmfid w/o user_fid2path mount option should fail
23637         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23638         cnt=$(ls -1 $DIR/$tdir | wc -l)
23639         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23640
23641         umount_client $MOUNT || error "failed to umount client"
23642         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23643                 error "failed to mount client'"
23644
23645         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23646         # rmfid should succeed
23647         cnt=$(ls -1 $DIR/$tdir | wc -l)
23648         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23649
23650         # rmfid shouldn't allow to remove files due to dir's permission
23651         chmod a+rwx $DIR/$tdir
23652         touch $DIR/$tdir/f
23653         ls -la $DIR/$tdir
23654         FID=$(lfs path2fid $DIR/$tdir/f)
23655         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23656
23657         umount_client $MOUNT || error "failed to umount client"
23658         mount_client $MOUNT "$MOUNT_OPTS" ||
23659                 error "failed to mount client'"
23660
23661 }
23662 run_test 421f "rmfid checks permissions"
23663
23664 test_421g() {
23665         local cnt
23666         local FIDS
23667
23668         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23669         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23670                 skip "Need MDS version at least 2.12.54"
23671
23672         mkdir -p $DIR/$tdir
23673         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23674         createmany -o $DIR/$tdir/striped_dir/f 512
23675         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23676         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23677
23678         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23679                 sed "s/[/][^:]*://g")
23680
23681         rm -f $DIR/$tdir/striped_dir/f1*
23682         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23683         removed=$((512 - cnt))
23684
23685         # few files have been just removed, so we expect
23686         # rmfid to fail on their fids
23687         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23688         [ $removed != $errors ] && error "$errors != $removed"
23689
23690         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23691         rm -rf $DIR/$tdir
23692         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23693 }
23694 run_test 421g "rmfid to return errors properly"
23695
23696 test_422() {
23697         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23698         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23699         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23700         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23701         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23702
23703         local amc=$(at_max_get client)
23704         local amo=$(at_max_get mds1)
23705         local timeout=`lctl get_param -n timeout`
23706
23707         at_max_set 0 client
23708         at_max_set 0 mds1
23709
23710 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23711         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23712                         fail_val=$(((2*timeout + 10)*1000))
23713         touch $DIR/$tdir/d3/file &
23714         sleep 2
23715 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23716         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23717                         fail_val=$((2*timeout + 5))
23718         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23719         local pid=$!
23720         sleep 1
23721         kill -9 $pid
23722         sleep $((2 * timeout))
23723         echo kill $pid
23724         kill -9 $pid
23725         lctl mark touch
23726         touch $DIR/$tdir/d2/file3
23727         touch $DIR/$tdir/d2/file4
23728         touch $DIR/$tdir/d2/file5
23729
23730         wait
23731         at_max_set $amc client
23732         at_max_set $amo mds1
23733
23734         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23735         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23736                 error "Watchdog is always throttled"
23737 }
23738 run_test 422 "kill a process with RPC in progress"
23739
23740 stat_test() {
23741     df -h $MOUNT &
23742     df -h $MOUNT &
23743     df -h $MOUNT &
23744     df -h $MOUNT &
23745     df -h $MOUNT &
23746     df -h $MOUNT &
23747 }
23748
23749 test_423() {
23750     local _stats
23751     # ensure statfs cache is expired
23752     sleep 2;
23753
23754     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23755     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23756
23757     return 0
23758 }
23759 run_test 423 "statfs should return a right data"
23760
23761 test_424() {
23762 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23763         $LCTL set_param fail_loc=0x80000522
23764         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23765         rm -f $DIR/$tfile
23766 }
23767 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23768
23769 test_425() {
23770         test_mkdir -c -1 $DIR/$tdir
23771         $LFS setstripe -c -1 $DIR/$tdir
23772
23773         lru_resize_disable "" 100
23774         stack_trap "lru_resize_enable" EXIT
23775
23776         sleep 5
23777
23778         for i in $(seq $((MDSCOUNT * 125))); do
23779                 local t=$DIR/$tdir/$tfile_$i
23780
23781                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23782                         error_noexit "Create file $t"
23783         done
23784         stack_trap "rm -rf $DIR/$tdir" EXIT
23785
23786         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23787                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23788                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23789
23790                 [ $lock_count -le $lru_size ] ||
23791                         error "osc lock count $lock_count > lru size $lru_size"
23792         done
23793
23794         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23795                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23796                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23797
23798                 [ $lock_count -le $lru_size ] ||
23799                         error "mdc lock count $lock_count > lru size $lru_size"
23800         done
23801 }
23802 run_test 425 "lock count should not exceed lru size"
23803
23804 test_426() {
23805         splice-test -r $DIR/$tfile
23806         splice-test -rd $DIR/$tfile
23807         splice-test $DIR/$tfile
23808         splice-test -d $DIR/$tfile
23809 }
23810 run_test 426 "splice test on Lustre"
23811
23812 lseek_test_430() {
23813         local offset
23814         local file=$1
23815
23816         # data at [200K, 400K)
23817         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23818                 error "256K->512K dd fails"
23819         # data at [2M, 3M)
23820         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23821                 error "2M->3M dd fails"
23822         # data at [4M, 5M)
23823         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23824                 error "4M->5M dd fails"
23825         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23826         # start at first component hole #1
23827         printf "Seeking hole from 1000 ... "
23828         offset=$(lseek_test -l 1000 $file)
23829         echo $offset
23830         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23831         printf "Seeking data from 1000 ... "
23832         offset=$(lseek_test -d 1000 $file)
23833         echo $offset
23834         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23835
23836         # start at first component data block
23837         printf "Seeking hole from 300000 ... "
23838         offset=$(lseek_test -l 300000 $file)
23839         echo $offset
23840         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23841         printf "Seeking data from 300000 ... "
23842         offset=$(lseek_test -d 300000 $file)
23843         echo $offset
23844         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23845
23846         # start at the first component but beyond end of object size
23847         printf "Seeking hole from 1000000 ... "
23848         offset=$(lseek_test -l 1000000 $file)
23849         echo $offset
23850         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23851         printf "Seeking data from 1000000 ... "
23852         offset=$(lseek_test -d 1000000 $file)
23853         echo $offset
23854         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23855
23856         # start at second component stripe 2 (empty file)
23857         printf "Seeking hole from 1500000 ... "
23858         offset=$(lseek_test -l 1500000 $file)
23859         echo $offset
23860         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23861         printf "Seeking data from 1500000 ... "
23862         offset=$(lseek_test -d 1500000 $file)
23863         echo $offset
23864         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23865
23866         # start at second component stripe 1 (all data)
23867         printf "Seeking hole from 3000000 ... "
23868         offset=$(lseek_test -l 3000000 $file)
23869         echo $offset
23870         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23871         printf "Seeking data from 3000000 ... "
23872         offset=$(lseek_test -d 3000000 $file)
23873         echo $offset
23874         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23875
23876         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23877                 error "2nd dd fails"
23878         echo "Add data block at 640K...1280K"
23879
23880         # start at before new data block, in hole
23881         printf "Seeking hole from 600000 ... "
23882         offset=$(lseek_test -l 600000 $file)
23883         echo $offset
23884         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23885         printf "Seeking data from 600000 ... "
23886         offset=$(lseek_test -d 600000 $file)
23887         echo $offset
23888         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23889
23890         # start at the first component new data block
23891         printf "Seeking hole from 1000000 ... "
23892         offset=$(lseek_test -l 1000000 $file)
23893         echo $offset
23894         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23895         printf "Seeking data from 1000000 ... "
23896         offset=$(lseek_test -d 1000000 $file)
23897         echo $offset
23898         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23899
23900         # start at second component stripe 2, new data
23901         printf "Seeking hole from 1200000 ... "
23902         offset=$(lseek_test -l 1200000 $file)
23903         echo $offset
23904         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23905         printf "Seeking data from 1200000 ... "
23906         offset=$(lseek_test -d 1200000 $file)
23907         echo $offset
23908         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23909
23910         # start beyond file end
23911         printf "Using offset > filesize ... "
23912         lseek_test -l 4000000 $file && error "lseek should fail"
23913         printf "Using offset > filesize ... "
23914         lseek_test -d 4000000 $file && error "lseek should fail"
23915
23916         printf "Done\n\n"
23917 }
23918
23919 test_430a() {
23920         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23921                 skip "MDT does not support SEEK_HOLE"
23922
23923         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23924                 skip "OST does not support SEEK_HOLE"
23925
23926         local file=$DIR/$tdir/$tfile
23927
23928         mkdir -p $DIR/$tdir
23929
23930         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23931         # OST stripe #1 will have continuous data at [1M, 3M)
23932         # OST stripe #2 is empty
23933         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23934         lseek_test_430 $file
23935         rm $file
23936         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23937         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23938         lseek_test_430 $file
23939         rm $file
23940         $LFS setstripe -c2 -S 512K $file
23941         echo "Two stripes, stripe size 512K"
23942         lseek_test_430 $file
23943         rm $file
23944         # FLR with stale mirror
23945         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23946                        -N -c2 -S 1M $file
23947         echo "Mirrored file:"
23948         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23949         echo "Plain 2 stripes 1M"
23950         lseek_test_430 $file
23951         rm $file
23952 }
23953 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23954
23955 test_430b() {
23956         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23957                 skip "OST does not support SEEK_HOLE"
23958
23959         local offset
23960         local file=$DIR/$tdir/$tfile
23961
23962         mkdir -p $DIR/$tdir
23963         # Empty layout lseek should fail
23964         $MCREATE $file
23965         # seek from 0
23966         printf "Seeking hole from 0 ... "
23967         lseek_test -l 0 $file && error "lseek should fail"
23968         printf "Seeking data from 0 ... "
23969         lseek_test -d 0 $file && error "lseek should fail"
23970         rm $file
23971
23972         # 1M-hole file
23973         $LFS setstripe -E 1M -c2 -E eof $file
23974         $TRUNCATE $file 1048576
23975         printf "Seeking hole from 1000000 ... "
23976         offset=$(lseek_test -l 1000000 $file)
23977         echo $offset
23978         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23979         printf "Seeking data from 1000000 ... "
23980         lseek_test -d 1000000 $file && error "lseek should fail"
23981         rm $file
23982
23983         # full component followed by non-inited one
23984         $LFS setstripe -E 1M -c2 -E eof $file
23985         dd if=/dev/urandom of=$file bs=1M count=1
23986         printf "Seeking hole from 1000000 ... "
23987         offset=$(lseek_test -l 1000000 $file)
23988         echo $offset
23989         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23990         printf "Seeking hole from 1048576 ... "
23991         lseek_test -l 1048576 $file && error "lseek should fail"
23992         # init second component and truncate back
23993         echo "123" >> $file
23994         $TRUNCATE $file 1048576
23995         printf "Seeking hole from 1000000 ... "
23996         offset=$(lseek_test -l 1000000 $file)
23997         echo $offset
23998         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23999         printf "Seeking hole from 1048576 ... "
24000         lseek_test -l 1048576 $file && error "lseek should fail"
24001         # boundary checks for big values
24002         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24003         offset=$(lseek_test -d 0 $file.10g)
24004         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24005         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24006         offset=$(lseek_test -d 0 $file.100g)
24007         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24008         return 0
24009 }
24010 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24011
24012 test_430c() {
24013         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24014                 skip "OST does not support SEEK_HOLE"
24015
24016         local file=$DIR/$tdir/$tfile
24017         local start
24018
24019         mkdir -p $DIR/$tdir
24020         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24021
24022         # cp version 8.33+ prefers lseek over fiemap
24023         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24024                 start=$SECONDS
24025                 time cp $file /dev/null
24026                 (( SECONDS - start < 5 )) ||
24027                         error "cp: too long runtime $((SECONDS - start))"
24028
24029         fi
24030         # tar version 1.29+ supports SEEK_HOLE/DATA
24031         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24032                 start=$SECONDS
24033                 time tar cS $file - | cat > /dev/null
24034                 (( SECONDS - start < 5 )) ||
24035                         error "tar: too long runtime $((SECONDS - start))"
24036         fi
24037 }
24038 run_test 430c "lseek: external tools check"
24039
24040 prep_801() {
24041         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24042         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24043                 skip "Need server version at least 2.9.55"
24044
24045         start_full_debug_logging
24046 }
24047
24048 post_801() {
24049         stop_full_debug_logging
24050 }
24051
24052 barrier_stat() {
24053         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24054                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24055                            awk '/The barrier for/ { print $7 }')
24056                 echo $st
24057         else
24058                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24059                 echo \'$st\'
24060         fi
24061 }
24062
24063 barrier_expired() {
24064         local expired
24065
24066         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24067                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24068                           awk '/will be expired/ { print $7 }')
24069         else
24070                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24071         fi
24072
24073         echo $expired
24074 }
24075
24076 test_801a() {
24077         prep_801
24078
24079         echo "Start barrier_freeze at: $(date)"
24080         #define OBD_FAIL_BARRIER_DELAY          0x2202
24081         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24082         # Do not reduce barrier time - See LU-11873
24083         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24084
24085         sleep 2
24086         local b_status=$(barrier_stat)
24087         echo "Got barrier status at: $(date)"
24088         [ "$b_status" = "'freezing_p1'" ] ||
24089                 error "(1) unexpected barrier status $b_status"
24090
24091         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24092         wait
24093         b_status=$(barrier_stat)
24094         [ "$b_status" = "'frozen'" ] ||
24095                 error "(2) unexpected barrier status $b_status"
24096
24097         local expired=$(barrier_expired)
24098         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24099         sleep $((expired + 3))
24100
24101         b_status=$(barrier_stat)
24102         [ "$b_status" = "'expired'" ] ||
24103                 error "(3) unexpected barrier status $b_status"
24104
24105         # Do not reduce barrier time - See LU-11873
24106         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24107                 error "(4) fail to freeze barrier"
24108
24109         b_status=$(barrier_stat)
24110         [ "$b_status" = "'frozen'" ] ||
24111                 error "(5) unexpected barrier status $b_status"
24112
24113         echo "Start barrier_thaw at: $(date)"
24114         #define OBD_FAIL_BARRIER_DELAY          0x2202
24115         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24116         do_facet mgs $LCTL barrier_thaw $FSNAME &
24117
24118         sleep 2
24119         b_status=$(barrier_stat)
24120         echo "Got barrier status at: $(date)"
24121         [ "$b_status" = "'thawing'" ] ||
24122                 error "(6) unexpected barrier status $b_status"
24123
24124         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24125         wait
24126         b_status=$(barrier_stat)
24127         [ "$b_status" = "'thawed'" ] ||
24128                 error "(7) unexpected barrier status $b_status"
24129
24130         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24131         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24132         do_facet mgs $LCTL barrier_freeze $FSNAME
24133
24134         b_status=$(barrier_stat)
24135         [ "$b_status" = "'failed'" ] ||
24136                 error "(8) unexpected barrier status $b_status"
24137
24138         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24139         do_facet mgs $LCTL barrier_thaw $FSNAME
24140
24141         post_801
24142 }
24143 run_test 801a "write barrier user interfaces and stat machine"
24144
24145 test_801b() {
24146         prep_801
24147
24148         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24149         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24150         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24151         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24152         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24153
24154         cancel_lru_locks mdc
24155
24156         # 180 seconds should be long enough
24157         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24158
24159         local b_status=$(barrier_stat)
24160         [ "$b_status" = "'frozen'" ] ||
24161                 error "(6) unexpected barrier status $b_status"
24162
24163         mkdir $DIR/$tdir/d0/d10 &
24164         mkdir_pid=$!
24165
24166         touch $DIR/$tdir/d1/f13 &
24167         touch_pid=$!
24168
24169         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24170         ln_pid=$!
24171
24172         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24173         mv_pid=$!
24174
24175         rm -f $DIR/$tdir/d4/f12 &
24176         rm_pid=$!
24177
24178         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24179
24180         # To guarantee taht the 'stat' is not blocked
24181         b_status=$(barrier_stat)
24182         [ "$b_status" = "'frozen'" ] ||
24183                 error "(8) unexpected barrier status $b_status"
24184
24185         # let above commands to run at background
24186         sleep 5
24187
24188         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24189         ps -p $touch_pid || error "(10) touch should be blocked"
24190         ps -p $ln_pid || error "(11) link should be blocked"
24191         ps -p $mv_pid || error "(12) rename should be blocked"
24192         ps -p $rm_pid || error "(13) unlink should be blocked"
24193
24194         b_status=$(barrier_stat)
24195         [ "$b_status" = "'frozen'" ] ||
24196                 error "(14) unexpected barrier status $b_status"
24197
24198         do_facet mgs $LCTL barrier_thaw $FSNAME
24199         b_status=$(barrier_stat)
24200         [ "$b_status" = "'thawed'" ] ||
24201                 error "(15) unexpected barrier status $b_status"
24202
24203         wait $mkdir_pid || error "(16) mkdir should succeed"
24204         wait $touch_pid || error "(17) touch should succeed"
24205         wait $ln_pid || error "(18) link should succeed"
24206         wait $mv_pid || error "(19) rename should succeed"
24207         wait $rm_pid || error "(20) unlink should succeed"
24208
24209         post_801
24210 }
24211 run_test 801b "modification will be blocked by write barrier"
24212
24213 test_801c() {
24214         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24215
24216         prep_801
24217
24218         stop mds2 || error "(1) Fail to stop mds2"
24219
24220         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24221
24222         local b_status=$(barrier_stat)
24223         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24224                 do_facet mgs $LCTL barrier_thaw $FSNAME
24225                 error "(2) unexpected barrier status $b_status"
24226         }
24227
24228         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24229                 error "(3) Fail to rescan barrier bitmap"
24230
24231         # Do not reduce barrier time - See LU-11873
24232         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24233
24234         b_status=$(barrier_stat)
24235         [ "$b_status" = "'frozen'" ] ||
24236                 error "(4) unexpected barrier status $b_status"
24237
24238         do_facet mgs $LCTL barrier_thaw $FSNAME
24239         b_status=$(barrier_stat)
24240         [ "$b_status" = "'thawed'" ] ||
24241                 error "(5) unexpected barrier status $b_status"
24242
24243         local devname=$(mdsdevname 2)
24244
24245         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24246
24247         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24248                 error "(7) Fail to rescan barrier bitmap"
24249
24250         post_801
24251 }
24252 run_test 801c "rescan barrier bitmap"
24253
24254 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24255 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24256 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24257 saved_MOUNT_OPTS=$MOUNT_OPTS
24258
24259 cleanup_802a() {
24260         trap 0
24261
24262         stopall
24263         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24264         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24265         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24266         MOUNT_OPTS=$saved_MOUNT_OPTS
24267         setupall
24268 }
24269
24270 test_802a() {
24271         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24272         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24273         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24274                 skip "Need server version at least 2.9.55"
24275
24276         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24277
24278         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24279
24280         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24281                 error "(2) Fail to copy"
24282
24283         trap cleanup_802a EXIT
24284
24285         # sync by force before remount as readonly
24286         sync; sync_all_data; sleep 3; sync_all_data
24287
24288         stopall
24289
24290         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24291         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24292         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24293
24294         echo "Mount the server as read only"
24295         setupall server_only || error "(3) Fail to start servers"
24296
24297         echo "Mount client without ro should fail"
24298         mount_client $MOUNT &&
24299                 error "(4) Mount client without 'ro' should fail"
24300
24301         echo "Mount client with ro should succeed"
24302         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24303         mount_client $MOUNT ||
24304                 error "(5) Mount client with 'ro' should succeed"
24305
24306         echo "Modify should be refused"
24307         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24308
24309         echo "Read should be allowed"
24310         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24311                 error "(7) Read should succeed under ro mode"
24312
24313         cleanup_802a
24314 }
24315 run_test 802a "simulate readonly device"
24316
24317 test_802b() {
24318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24319         remote_mds_nodsh && skip "remote MDS with nodsh"
24320
24321         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24322                 skip "readonly option not available"
24323
24324         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24325
24326         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24327                 error "(2) Fail to copy"
24328
24329         # write back all cached data before setting MDT to readonly
24330         cancel_lru_locks
24331         sync_all_data
24332
24333         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24334         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24335
24336         echo "Modify should be refused"
24337         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24338
24339         echo "Read should be allowed"
24340         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24341                 error "(7) Read should succeed under ro mode"
24342
24343         # disable readonly
24344         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24345 }
24346 run_test 802b "be able to set MDTs to readonly"
24347
24348 test_803a() {
24349         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24350         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24351                 skip "MDS needs to be newer than 2.10.54"
24352
24353         mkdir -p $DIR/$tdir
24354         # Create some objects on all MDTs to trigger related logs objects
24355         for idx in $(seq $MDSCOUNT); do
24356                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24357                         $DIR/$tdir/dir${idx} ||
24358                         error "Fail to create $DIR/$tdir/dir${idx}"
24359         done
24360
24361         sync; sleep 3
24362         wait_delete_completed # ensure old test cleanups are finished
24363         echo "before create:"
24364         $LFS df -i $MOUNT
24365         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24366
24367         for i in {1..10}; do
24368                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24369                         error "Fail to create $DIR/$tdir/foo$i"
24370         done
24371
24372         sync; sleep 3
24373         echo "after create:"
24374         $LFS df -i $MOUNT
24375         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24376
24377         # allow for an llog to be cleaned up during the test
24378         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24379                 error "before ($before_used) + 10 > after ($after_used)"
24380
24381         for i in {1..10}; do
24382                 rm -rf $DIR/$tdir/foo$i ||
24383                         error "Fail to remove $DIR/$tdir/foo$i"
24384         done
24385
24386         sleep 3 # avoid MDT return cached statfs
24387         wait_delete_completed
24388         echo "after unlink:"
24389         $LFS df -i $MOUNT
24390         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24391
24392         # allow for an llog to be created during the test
24393         [ $after_used -le $((before_used + 1)) ] ||
24394                 error "after ($after_used) > before ($before_used) + 1"
24395 }
24396 run_test 803a "verify agent object for remote object"
24397
24398 test_803b() {
24399         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24400         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24401                 skip "MDS needs to be newer than 2.13.56"
24402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24403
24404         for i in $(seq 0 $((MDSCOUNT - 1))); do
24405                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24406         done
24407
24408         local before=0
24409         local after=0
24410
24411         local tmp
24412
24413         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24414         for i in $(seq 0 $((MDSCOUNT - 1))); do
24415                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24416                         awk '/getattr/ { print $2 }')
24417                 before=$((before + tmp))
24418         done
24419         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24420         for i in $(seq 0 $((MDSCOUNT - 1))); do
24421                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24422                         awk '/getattr/ { print $2 }')
24423                 after=$((after + tmp))
24424         done
24425
24426         [ $before -eq $after ] || error "getattr count $before != $after"
24427 }
24428 run_test 803b "remote object can getattr from cache"
24429
24430 test_804() {
24431         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24432         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24433                 skip "MDS needs to be newer than 2.10.54"
24434         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24435
24436         mkdir -p $DIR/$tdir
24437         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24438                 error "Fail to create $DIR/$tdir/dir0"
24439
24440         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24441         local dev=$(mdsdevname 2)
24442
24443         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24444                 grep ${fid} || error "NOT found agent entry for dir0"
24445
24446         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24447                 error "Fail to create $DIR/$tdir/dir1"
24448
24449         touch $DIR/$tdir/dir1/foo0 ||
24450                 error "Fail to create $DIR/$tdir/dir1/foo0"
24451         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24452         local rc=0
24453
24454         for idx in $(seq $MDSCOUNT); do
24455                 dev=$(mdsdevname $idx)
24456                 do_facet mds${idx} \
24457                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24458                         grep ${fid} && rc=$idx
24459         done
24460
24461         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24462                 error "Fail to rename foo0 to foo1"
24463         if [ $rc -eq 0 ]; then
24464                 for idx in $(seq $MDSCOUNT); do
24465                         dev=$(mdsdevname $idx)
24466                         do_facet mds${idx} \
24467                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24468                         grep ${fid} && rc=$idx
24469                 done
24470         fi
24471
24472         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24473                 error "Fail to rename foo1 to foo2"
24474         if [ $rc -eq 0 ]; then
24475                 for idx in $(seq $MDSCOUNT); do
24476                         dev=$(mdsdevname $idx)
24477                         do_facet mds${idx} \
24478                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24479                         grep ${fid} && rc=$idx
24480                 done
24481         fi
24482
24483         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24484
24485         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24486                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24487         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24488                 error "Fail to rename foo2 to foo0"
24489         unlink $DIR/$tdir/dir1/foo0 ||
24490                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24491         rm -rf $DIR/$tdir/dir0 ||
24492                 error "Fail to rm $DIR/$tdir/dir0"
24493
24494         for idx in $(seq $MDSCOUNT); do
24495                 dev=$(mdsdevname $idx)
24496                 rc=0
24497
24498                 stop mds${idx}
24499                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24500                         rc=$?
24501                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24502                         error "mount mds$idx failed"
24503                 df $MOUNT > /dev/null 2>&1
24504
24505                 # e2fsck should not return error
24506                 [ $rc -eq 0 ] ||
24507                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24508         done
24509 }
24510 run_test 804 "verify agent entry for remote entry"
24511
24512 cleanup_805() {
24513         do_facet $SINGLEMDS zfs set quota=$old $fsset
24514         unlinkmany $DIR/$tdir/f- 1000000
24515         trap 0
24516 }
24517
24518 test_805() {
24519         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24520         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24521         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24522                 skip "netfree not implemented before 0.7"
24523         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24524                 skip "Need MDS version at least 2.10.57"
24525
24526         local fsset
24527         local freekb
24528         local usedkb
24529         local old
24530         local quota
24531         local pref="osd-zfs.$FSNAME-MDT0000."
24532
24533         # limit available space on MDS dataset to meet nospace issue
24534         # quickly. then ZFS 0.7.2 can use reserved space if asked
24535         # properly (using netfree flag in osd_declare_destroy()
24536         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24537         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24538                 gawk '{print $3}')
24539         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24540         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24541         let "usedkb=usedkb-freekb"
24542         let "freekb=freekb/2"
24543         if let "freekb > 5000"; then
24544                 let "freekb=5000"
24545         fi
24546         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24547         trap cleanup_805 EXIT
24548         mkdir $DIR/$tdir
24549         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24550                 error "Can't set PFL layout"
24551         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24552         rm -rf $DIR/$tdir || error "not able to remove"
24553         do_facet $SINGLEMDS zfs set quota=$old $fsset
24554         trap 0
24555 }
24556 run_test 805 "ZFS can remove from full fs"
24557
24558 # Size-on-MDS test
24559 check_lsom_data()
24560 {
24561         local file=$1
24562         local size=$($LFS getsom -s $file)
24563         local expect=$(stat -c %s $file)
24564
24565         [[ $size == $expect ]] ||
24566                 error "$file expected size: $expect, got: $size"
24567
24568         local blocks=$($LFS getsom -b $file)
24569         expect=$(stat -c %b $file)
24570         [[ $blocks == $expect ]] ||
24571                 error "$file expected blocks: $expect, got: $blocks"
24572 }
24573
24574 check_lsom_size()
24575 {
24576         local size=$($LFS getsom -s $1)
24577         local expect=$2
24578
24579         [[ $size == $expect ]] ||
24580                 error "$file expected size: $expect, got: $size"
24581 }
24582
24583 test_806() {
24584         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24585                 skip "Need MDS version at least 2.11.52"
24586
24587         local bs=1048576
24588
24589         touch $DIR/$tfile || error "touch $tfile failed"
24590
24591         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24592         save_lustre_params client "llite.*.xattr_cache" > $save
24593         lctl set_param llite.*.xattr_cache=0
24594         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24595
24596         # single-threaded write
24597         echo "Test SOM for single-threaded write"
24598         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24599                 error "write $tfile failed"
24600         check_lsom_size $DIR/$tfile $bs
24601
24602         local num=32
24603         local size=$(($num * $bs))
24604         local offset=0
24605         local i
24606
24607         echo "Test SOM for single client multi-threaded($num) write"
24608         $TRUNCATE $DIR/$tfile 0
24609         for ((i = 0; i < $num; i++)); do
24610                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24611                 local pids[$i]=$!
24612                 offset=$((offset + $bs))
24613         done
24614         for (( i=0; i < $num; i++ )); do
24615                 wait ${pids[$i]}
24616         done
24617         check_lsom_size $DIR/$tfile $size
24618
24619         $TRUNCATE $DIR/$tfile 0
24620         for ((i = 0; i < $num; i++)); do
24621                 offset=$((offset - $bs))
24622                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24623                 local pids[$i]=$!
24624         done
24625         for (( i=0; i < $num; i++ )); do
24626                 wait ${pids[$i]}
24627         done
24628         check_lsom_size $DIR/$tfile $size
24629
24630         # multi-client writes
24631         num=$(get_node_count ${CLIENTS//,/ })
24632         size=$(($num * $bs))
24633         offset=0
24634         i=0
24635
24636         echo "Test SOM for multi-client ($num) writes"
24637         $TRUNCATE $DIR/$tfile 0
24638         for client in ${CLIENTS//,/ }; do
24639                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24640                 local pids[$i]=$!
24641                 i=$((i + 1))
24642                 offset=$((offset + $bs))
24643         done
24644         for (( i=0; i < $num; i++ )); do
24645                 wait ${pids[$i]}
24646         done
24647         check_lsom_size $DIR/$tfile $offset
24648
24649         i=0
24650         $TRUNCATE $DIR/$tfile 0
24651         for client in ${CLIENTS//,/ }; do
24652                 offset=$((offset - $bs))
24653                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24654                 local pids[$i]=$!
24655                 i=$((i + 1))
24656         done
24657         for (( i=0; i < $num; i++ )); do
24658                 wait ${pids[$i]}
24659         done
24660         check_lsom_size $DIR/$tfile $size
24661
24662         # verify truncate
24663         echo "Test SOM for truncate"
24664         $TRUNCATE $DIR/$tfile 1048576
24665         check_lsom_size $DIR/$tfile 1048576
24666         $TRUNCATE $DIR/$tfile 1234
24667         check_lsom_size $DIR/$tfile 1234
24668
24669         # verify SOM blocks count
24670         echo "Verify SOM block count"
24671         $TRUNCATE $DIR/$tfile 0
24672         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24673                 error "failed to write file $tfile"
24674         check_lsom_data $DIR/$tfile
24675 }
24676 run_test 806 "Verify Lazy Size on MDS"
24677
24678 test_807() {
24679         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24680         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24681                 skip "Need MDS version at least 2.11.52"
24682
24683         # Registration step
24684         changelog_register || error "changelog_register failed"
24685         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24686         changelog_users $SINGLEMDS | grep -q $cl_user ||
24687                 error "User $cl_user not found in changelog_users"
24688
24689         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24690         save_lustre_params client "llite.*.xattr_cache" > $save
24691         lctl set_param llite.*.xattr_cache=0
24692         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24693
24694         rm -rf $DIR/$tdir || error "rm $tdir failed"
24695         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24696         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24697         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24698         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24699                 error "truncate $tdir/trunc failed"
24700
24701         local bs=1048576
24702         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24703                 error "write $tfile failed"
24704
24705         # multi-client wirtes
24706         local num=$(get_node_count ${CLIENTS//,/ })
24707         local offset=0
24708         local i=0
24709
24710         echo "Test SOM for multi-client ($num) writes"
24711         touch $DIR/$tfile || error "touch $tfile failed"
24712         $TRUNCATE $DIR/$tfile 0
24713         for client in ${CLIENTS//,/ }; do
24714                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24715                 local pids[$i]=$!
24716                 i=$((i + 1))
24717                 offset=$((offset + $bs))
24718         done
24719         for (( i=0; i < $num; i++ )); do
24720                 wait ${pids[$i]}
24721         done
24722
24723         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24724         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24725         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24726         check_lsom_data $DIR/$tdir/trunc
24727         check_lsom_data $DIR/$tdir/single_dd
24728         check_lsom_data $DIR/$tfile
24729
24730         rm -rf $DIR/$tdir
24731         # Deregistration step
24732         changelog_deregister || error "changelog_deregister failed"
24733 }
24734 run_test 807 "verify LSOM syncing tool"
24735
24736 check_som_nologged()
24737 {
24738         local lines=$($LFS changelog $FSNAME-MDT0000 |
24739                 grep 'x=trusted.som' | wc -l)
24740         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24741 }
24742
24743 test_808() {
24744         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24745                 skip "Need MDS version at least 2.11.55"
24746
24747         # Registration step
24748         changelog_register || error "changelog_register failed"
24749
24750         touch $DIR/$tfile || error "touch $tfile failed"
24751         check_som_nologged
24752
24753         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24754                 error "write $tfile failed"
24755         check_som_nologged
24756
24757         $TRUNCATE $DIR/$tfile 1234
24758         check_som_nologged
24759
24760         $TRUNCATE $DIR/$tfile 1048576
24761         check_som_nologged
24762
24763         # Deregistration step
24764         changelog_deregister || error "changelog_deregister failed"
24765 }
24766 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24767
24768 check_som_nodata()
24769 {
24770         $LFS getsom $1
24771         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24772 }
24773
24774 test_809() {
24775         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24776                 skip "Need MDS version at least 2.11.56"
24777
24778         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24779                 error "failed to create DoM-only file $DIR/$tfile"
24780         touch $DIR/$tfile || error "touch $tfile failed"
24781         check_som_nodata $DIR/$tfile
24782
24783         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24784                 error "write $tfile failed"
24785         check_som_nodata $DIR/$tfile
24786
24787         $TRUNCATE $DIR/$tfile 1234
24788         check_som_nodata $DIR/$tfile
24789
24790         $TRUNCATE $DIR/$tfile 4097
24791         check_som_nodata $DIR/$file
24792 }
24793 run_test 809 "Verify no SOM xattr store for DoM-only files"
24794
24795 test_810() {
24796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24797         $GSS && skip_env "could not run with gss"
24798         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24799                 skip "OST < 2.12.58 doesn't align checksum"
24800
24801         set_checksums 1
24802         stack_trap "set_checksums $ORIG_CSUM" EXIT
24803         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24804
24805         local csum
24806         local before
24807         local after
24808         for csum in $CKSUM_TYPES; do
24809                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24810                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24811                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24812                         eval set -- $i
24813                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24814                         before=$(md5sum $DIR/$tfile)
24815                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24816                         after=$(md5sum $DIR/$tfile)
24817                         [ "$before" == "$after" ] ||
24818                                 error "$csum: $before != $after bs=$1 seek=$2"
24819                 done
24820         done
24821 }
24822 run_test 810 "partial page writes on ZFS (LU-11663)"
24823
24824 test_812a() {
24825         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24826                 skip "OST < 2.12.51 doesn't support this fail_loc"
24827
24828         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24829         # ensure ost1 is connected
24830         stat $DIR/$tfile >/dev/null || error "can't stat"
24831         wait_osc_import_state client ost1 FULL
24832         # no locks, no reqs to let the connection idle
24833         cancel_lru_locks osc
24834
24835         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24836 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24837         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24838         wait_osc_import_state client ost1 CONNECTING
24839         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24840
24841         stat $DIR/$tfile >/dev/null || error "can't stat file"
24842 }
24843 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24844
24845 test_812b() { # LU-12378
24846         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24847                 skip "OST < 2.12.51 doesn't support this fail_loc"
24848
24849         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24850         # ensure ost1 is connected
24851         stat $DIR/$tfile >/dev/null || error "can't stat"
24852         wait_osc_import_state client ost1 FULL
24853         # no locks, no reqs to let the connection idle
24854         cancel_lru_locks osc
24855
24856         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24857 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24858         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24859         wait_osc_import_state client ost1 CONNECTING
24860         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24861
24862         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24863         wait_osc_import_state client ost1 IDLE
24864 }
24865 run_test 812b "do not drop no resend request for idle connect"
24866
24867 test_813() {
24868         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24869         [ -z "$file_heat_sav" ] && skip "no file heat support"
24870
24871         local readsample
24872         local writesample
24873         local readbyte
24874         local writebyte
24875         local readsample1
24876         local writesample1
24877         local readbyte1
24878         local writebyte1
24879
24880         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24881         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24882
24883         $LCTL set_param -n llite.*.file_heat=1
24884         echo "Turn on file heat"
24885         echo "Period second: $period_second, Decay percentage: $decay_pct"
24886
24887         echo "QQQQ" > $DIR/$tfile
24888         echo "QQQQ" > $DIR/$tfile
24889         echo "QQQQ" > $DIR/$tfile
24890         cat $DIR/$tfile > /dev/null
24891         cat $DIR/$tfile > /dev/null
24892         cat $DIR/$tfile > /dev/null
24893         cat $DIR/$tfile > /dev/null
24894
24895         local out=$($LFS heat_get $DIR/$tfile)
24896
24897         $LFS heat_get $DIR/$tfile
24898         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24899         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24900         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24901         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24902
24903         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24904         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24905         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24906         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24907
24908         sleep $((period_second + 3))
24909         echo "Sleep $((period_second + 3)) seconds..."
24910         # The recursion formula to calculate the heat of the file f is as
24911         # follow:
24912         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24913         # Where Hi is the heat value in the period between time points i*I and
24914         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24915         # to the weight of Ci.
24916         out=$($LFS heat_get $DIR/$tfile)
24917         $LFS heat_get $DIR/$tfile
24918         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24919         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24920         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24921         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24922
24923         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24924                 error "read sample ($readsample) is wrong"
24925         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24926                 error "write sample ($writesample) is wrong"
24927         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24928                 error "read bytes ($readbyte) is wrong"
24929         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24930                 error "write bytes ($writebyte) is wrong"
24931
24932         echo "QQQQ" > $DIR/$tfile
24933         echo "QQQQ" > $DIR/$tfile
24934         echo "QQQQ" > $DIR/$tfile
24935         cat $DIR/$tfile > /dev/null
24936         cat $DIR/$tfile > /dev/null
24937         cat $DIR/$tfile > /dev/null
24938         cat $DIR/$tfile > /dev/null
24939
24940         sleep $((period_second + 3))
24941         echo "Sleep $((period_second + 3)) seconds..."
24942
24943         out=$($LFS heat_get $DIR/$tfile)
24944         $LFS heat_get $DIR/$tfile
24945         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24946         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24947         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24948         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24949
24950         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24951                 4 * $decay_pct) / 100") -eq 1 ] ||
24952                 error "read sample ($readsample1) is wrong"
24953         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24954                 3 * $decay_pct) / 100") -eq 1 ] ||
24955                 error "write sample ($writesample1) is wrong"
24956         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24957                 20 * $decay_pct) / 100") -eq 1 ] ||
24958                 error "read bytes ($readbyte1) is wrong"
24959         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24960                 15 * $decay_pct) / 100") -eq 1 ] ||
24961                 error "write bytes ($writebyte1) is wrong"
24962
24963         echo "Turn off file heat for the file $DIR/$tfile"
24964         $LFS heat_set -o $DIR/$tfile
24965
24966         echo "QQQQ" > $DIR/$tfile
24967         echo "QQQQ" > $DIR/$tfile
24968         echo "QQQQ" > $DIR/$tfile
24969         cat $DIR/$tfile > /dev/null
24970         cat $DIR/$tfile > /dev/null
24971         cat $DIR/$tfile > /dev/null
24972         cat $DIR/$tfile > /dev/null
24973
24974         out=$($LFS heat_get $DIR/$tfile)
24975         $LFS heat_get $DIR/$tfile
24976         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24977         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24978         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24979         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24980
24981         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24982         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24983         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24984         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24985
24986         echo "Trun on file heat for the file $DIR/$tfile"
24987         $LFS heat_set -O $DIR/$tfile
24988
24989         echo "QQQQ" > $DIR/$tfile
24990         echo "QQQQ" > $DIR/$tfile
24991         echo "QQQQ" > $DIR/$tfile
24992         cat $DIR/$tfile > /dev/null
24993         cat $DIR/$tfile > /dev/null
24994         cat $DIR/$tfile > /dev/null
24995         cat $DIR/$tfile > /dev/null
24996
24997         out=$($LFS heat_get $DIR/$tfile)
24998         $LFS heat_get $DIR/$tfile
24999         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25000         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25001         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25002         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25003
25004         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25005         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25006         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25007         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25008
25009         $LFS heat_set -c $DIR/$tfile
25010         $LCTL set_param -n llite.*.file_heat=0
25011         echo "Turn off file heat support for the Lustre filesystem"
25012
25013         echo "QQQQ" > $DIR/$tfile
25014         echo "QQQQ" > $DIR/$tfile
25015         echo "QQQQ" > $DIR/$tfile
25016         cat $DIR/$tfile > /dev/null
25017         cat $DIR/$tfile > /dev/null
25018         cat $DIR/$tfile > /dev/null
25019         cat $DIR/$tfile > /dev/null
25020
25021         out=$($LFS heat_get $DIR/$tfile)
25022         $LFS heat_get $DIR/$tfile
25023         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25024         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25025         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25026         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25027
25028         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25029         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25030         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25031         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25032
25033         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25034         rm -f $DIR/$tfile
25035 }
25036 run_test 813 "File heat verfication"
25037
25038 test_814()
25039 {
25040         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25041         echo -n y >> $DIR/$tfile
25042         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25043         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25044 }
25045 run_test 814 "sparse cp works as expected (LU-12361)"
25046
25047 test_815()
25048 {
25049         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25050         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25051 }
25052 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25053
25054 test_816() {
25055         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25056         # ensure ost1 is connected
25057         stat $DIR/$tfile >/dev/null || error "can't stat"
25058         wait_osc_import_state client ost1 FULL
25059         # no locks, no reqs to let the connection idle
25060         cancel_lru_locks osc
25061         lru_resize_disable osc
25062         local before
25063         local now
25064         before=$($LCTL get_param -n \
25065                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25066
25067         wait_osc_import_state client ost1 IDLE
25068         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25069         now=$($LCTL get_param -n \
25070               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25071         [ $before == $now ] || error "lru_size changed $before != $now"
25072 }
25073 run_test 816 "do not reset lru_resize on idle reconnect"
25074
25075 cleanup_817() {
25076         umount $tmpdir
25077         exportfs -u localhost:$DIR/nfsexp
25078         rm -rf $DIR/nfsexp
25079 }
25080
25081 test_817() {
25082         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25083
25084         mkdir -p $DIR/nfsexp
25085         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25086                 error "failed to export nfs"
25087
25088         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25089         stack_trap cleanup_817 EXIT
25090
25091         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25092                 error "failed to mount nfs to $tmpdir"
25093
25094         cp /bin/true $tmpdir
25095         $DIR/nfsexp/true || error "failed to execute 'true' command"
25096 }
25097 run_test 817 "nfsd won't cache write lock for exec file"
25098
25099 test_818() {
25100         mkdir $DIR/$tdir
25101         $LFS setstripe -c1 -i0 $DIR/$tfile
25102         $LFS setstripe -c1 -i1 $DIR/$tfile
25103         stop $SINGLEMDS
25104         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25105         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25106         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25107                 error "start $SINGLEMDS failed"
25108         rm -rf $DIR/$tdir
25109 }
25110 run_test 818 "unlink with failed llog"
25111
25112 test_819a() {
25113         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25114         cancel_lru_locks osc
25115         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25116         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25117         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25118         rm -f $TDIR/$tfile
25119 }
25120 run_test 819a "too big niobuf in read"
25121
25122 test_819b() {
25123         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25124         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25125         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25126         cancel_lru_locks osc
25127         sleep 1
25128         rm -f $TDIR/$tfile
25129 }
25130 run_test 819b "too big niobuf in write"
25131
25132
25133 function test_820_start_ost() {
25134         sleep 5
25135
25136         for num in $(seq $OSTCOUNT); do
25137                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25138         done
25139 }
25140
25141 test_820() {
25142         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25143
25144         mkdir $DIR/$tdir
25145         umount_client $MOUNT || error "umount failed"
25146         for num in $(seq $OSTCOUNT); do
25147                 stop ost$num
25148         done
25149
25150         # mount client with no active OSTs
25151         # so that the client can't initialize max LOV EA size
25152         # from OSC notifications
25153         mount_client $MOUNT || error "mount failed"
25154         # delay OST starting to keep this 0 max EA size for a while
25155         test_820_start_ost &
25156
25157         # create a directory on MDS2
25158         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25159                 error "Failed to create directory"
25160         # open intent should update default EA size
25161         # see mdc_update_max_ea_from_body()
25162         # notice this is the very first RPC to MDS2
25163         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25164         ret=$?
25165         echo $out
25166         # With SSK, this situation can lead to -EPERM being returned.
25167         # In that case, simply retry.
25168         if [ $ret -ne 0 ] && $SHARED_KEY; then
25169                 if echo "$out" | grep -q "not permitted"; then
25170                         cp /etc/services $DIR/$tdir/mds2
25171                         ret=$?
25172                 fi
25173         fi
25174         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25175 }
25176 run_test 820 "update max EA from open intent"
25177
25178 #
25179 # tests that do cleanup/setup should be run at the end
25180 #
25181
25182 test_900() {
25183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25184         local ls
25185
25186         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25187         $LCTL set_param fail_loc=0x903
25188
25189         cancel_lru_locks MGC
25190
25191         FAIL_ON_ERROR=true cleanup
25192         FAIL_ON_ERROR=true setup
25193 }
25194 run_test 900 "umount should not race with any mgc requeue thread"
25195
25196 # LUS-6253/LU-11185
25197 test_901() {
25198         local oldc
25199         local newc
25200         local olds
25201         local news
25202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25203
25204         # some get_param have a bug to handle dot in param name
25205         cancel_lru_locks MGC
25206         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25207         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25208         umount_client $MOUNT || error "umount failed"
25209         mount_client $MOUNT || error "mount failed"
25210         cancel_lru_locks MGC
25211         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25212         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25213
25214         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25215         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25216
25217         return 0
25218 }
25219 run_test 901 "don't leak a mgc lock on client umount"
25220
25221 # LU-13377
25222 test_902() {
25223         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25224                 skip "client does not have LU-13377 fix"
25225         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25226         $LCTL set_param fail_loc=0x1415
25227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25228         cancel_lru_locks osc
25229         rm -f $DIR/$tfile
25230 }
25231 run_test 902 "test short write doesn't hang lustre"
25232
25233 complete $SECONDS
25234 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25235 check_and_cleanup_lustre
25236 if [ "$I_MOUNTED" != "yes" ]; then
25237         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25238 fi
25239 exit_status