Whamcloud - gitweb
LU-14583 llapi: handle symlinks in llapi_file_get_stripe()
[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 client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         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
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 test_27Q() {
3323         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3324
3325         test_mkdir $DIR/$tdir-1
3326         test_mkdir $DIR/$tdir-2
3327
3328         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3329         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3330
3331         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3332         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3333
3334         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3335         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3336
3337         # Create some bad symlinks and ensure that we don't loop
3338         # forever or something. These should return ELOOP (40) and
3339         # ENOENT (2) but I don't want to test for that because there's
3340         # always some weirdo architecture that needs to ruin
3341         # everything by defining these error numbers differently.
3342
3343         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3344         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3345
3346         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3347         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3348
3349         return 0
3350 }
3351 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3352
3353 # createtest also checks that device nodes are created and
3354 # then visible correctly (#2091)
3355 test_28() { # bug 2091
3356         test_mkdir $DIR/d28
3357         $CREATETEST $DIR/d28/ct || error "createtest failed"
3358 }
3359 run_test 28 "create/mknod/mkdir with bad file types ============"
3360
3361 test_29() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         sync; sleep 1; sync # flush out any dirty pages from previous tests
3365         cancel_lru_locks
3366         test_mkdir $DIR/d29
3367         touch $DIR/d29/foo
3368         log 'first d29'
3369         ls -l $DIR/d29
3370
3371         declare -i LOCKCOUNTORIG=0
3372         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3373                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3374         done
3375         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3376
3377         declare -i LOCKUNUSEDCOUNTORIG=0
3378         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3379                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3380         done
3381
3382         log 'second d29'
3383         ls -l $DIR/d29
3384         log 'done'
3385
3386         declare -i LOCKCOUNTCURRENT=0
3387         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3388                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3389         done
3390
3391         declare -i LOCKUNUSEDCOUNTCURRENT=0
3392         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3393                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3394         done
3395
3396         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3397                 $LCTL set_param -n ldlm.dump_namespaces ""
3398                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3399                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3400                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3401                 return 2
3402         fi
3403         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3404                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3405                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3406                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3407                 return 3
3408         fi
3409 }
3410 run_test 29 "IT_GETATTR regression  ============================"
3411
3412 test_30a() { # was test_30
3413         cp $(which ls) $DIR || cp /bin/ls $DIR
3414         $DIR/ls / || error "Can't execute binary from lustre"
3415         rm $DIR/ls
3416 }
3417 run_test 30a "execute binary from Lustre (execve) =============="
3418
3419 test_30b() {
3420         cp `which ls` $DIR || cp /bin/ls $DIR
3421         chmod go+rx $DIR/ls
3422         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3423         rm $DIR/ls
3424 }
3425 run_test 30b "execute binary from Lustre as non-root ==========="
3426
3427 test_30c() { # b=22376
3428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3429
3430         cp $(which ls) $DIR || cp /bin/ls $DIR
3431         chmod a-rw $DIR/ls
3432         cancel_lru_locks mdc
3433         cancel_lru_locks osc
3434         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3435         rm -f $DIR/ls
3436 }
3437 run_test 30c "execute binary from Lustre without read perms ===="
3438
3439 test_30d() {
3440         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3441
3442         for i in {1..10}; do
3443                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3444                 local PID=$!
3445                 sleep 1
3446                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3447                 wait $PID || error "executing dd from Lustre failed"
3448                 rm -f $DIR/$tfile
3449         done
3450
3451         rm -f $DIR/dd
3452 }
3453 run_test 30d "execute binary from Lustre while clear locks"
3454
3455 test_31a() {
3456         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3457         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3458 }
3459 run_test 31a "open-unlink file =================================="
3460
3461 test_31b() {
3462         touch $DIR/f31 || error "touch $DIR/f31 failed"
3463         ln $DIR/f31 $DIR/f31b || error "ln failed"
3464         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3465         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3466 }
3467 run_test 31b "unlink file with multiple links while open ======="
3468
3469 test_31c() {
3470         touch $DIR/f31 || error "touch $DIR/f31 failed"
3471         ln $DIR/f31 $DIR/f31c || error "ln failed"
3472         multiop_bg_pause $DIR/f31 O_uc ||
3473                 error "multiop_bg_pause for $DIR/f31 failed"
3474         MULTIPID=$!
3475         $MULTIOP $DIR/f31c Ouc
3476         kill -USR1 $MULTIPID
3477         wait $MULTIPID
3478 }
3479 run_test 31c "open-unlink file with multiple links ============="
3480
3481 test_31d() {
3482         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3483         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3484 }
3485 run_test 31d "remove of open directory ========================="
3486
3487 test_31e() { # bug 2904
3488         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3489 }
3490 run_test 31e "remove of open non-empty directory ==============="
3491
3492 test_31f() { # bug 4554
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         set -vx
3496         test_mkdir $DIR/d31f
3497         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3498         cp /etc/hosts $DIR/d31f
3499         ls -l $DIR/d31f
3500         $LFS getstripe $DIR/d31f/hosts
3501         multiop_bg_pause $DIR/d31f D_c || return 1
3502         MULTIPID=$!
3503
3504         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3505         test_mkdir $DIR/d31f
3506         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3507         cp /etc/hosts $DIR/d31f
3508         ls -l $DIR/d31f
3509         $LFS getstripe $DIR/d31f/hosts
3510         multiop_bg_pause $DIR/d31f D_c || return 1
3511         MULTIPID2=$!
3512
3513         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3514         wait $MULTIPID || error "first opendir $MULTIPID failed"
3515
3516         sleep 6
3517
3518         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3519         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3520         set +vx
3521 }
3522 run_test 31f "remove of open directory with open-unlink file ==="
3523
3524 test_31g() {
3525         echo "-- cross directory link --"
3526         test_mkdir -c1 $DIR/${tdir}ga
3527         test_mkdir -c1 $DIR/${tdir}gb
3528         touch $DIR/${tdir}ga/f
3529         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3530         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3531         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3532         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3533         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3534 }
3535 run_test 31g "cross directory link==============="
3536
3537 test_31h() {
3538         echo "-- cross directory link --"
3539         test_mkdir -c1 $DIR/${tdir}
3540         test_mkdir -c1 $DIR/${tdir}/dir
3541         touch $DIR/${tdir}/f
3542         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3543         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3544         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3545         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3546         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3547 }
3548 run_test 31h "cross directory link under child==============="
3549
3550 test_31i() {
3551         echo "-- cross directory link --"
3552         test_mkdir -c1 $DIR/$tdir
3553         test_mkdir -c1 $DIR/$tdir/dir
3554         touch $DIR/$tdir/dir/f
3555         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3556         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3557         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3558         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3559         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3560 }
3561 run_test 31i "cross directory link under parent==============="
3562
3563 test_31j() {
3564         test_mkdir -c1 -p $DIR/$tdir
3565         test_mkdir -c1 -p $DIR/$tdir/dir1
3566         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3567         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3568         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3570         return 0
3571 }
3572 run_test 31j "link for directory==============="
3573
3574 test_31k() {
3575         test_mkdir -c1 -p $DIR/$tdir
3576         touch $DIR/$tdir/s
3577         touch $DIR/$tdir/exist
3578         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3579         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3580         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3581         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3582         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3583         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3585         return 0
3586 }
3587 run_test 31k "link to file: the same, non-existing, dir==============="
3588
3589 test_31m() {
3590         mkdir $DIR/d31m
3591         touch $DIR/d31m/s
3592         mkdir $DIR/d31m2
3593         touch $DIR/d31m2/exist
3594         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3595         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3596         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3597         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3598         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3600         return 0
3601 }
3602 run_test 31m "link to file: the same, non-existing, dir==============="
3603
3604 test_31n() {
3605         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3606         nlink=$(stat --format=%h $DIR/$tfile)
3607         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3608         local fd=$(free_fd)
3609         local cmd="exec $fd<$DIR/$tfile"
3610         eval $cmd
3611         cmd="exec $fd<&-"
3612         trap "eval $cmd" EXIT
3613         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3614         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3615         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3616         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3617         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3618         eval $cmd
3619 }
3620 run_test 31n "check link count of unlinked file"
3621
3622 link_one() {
3623         local tempfile=$(mktemp $1_XXXXXX)
3624         mlink $tempfile $1 2> /dev/null &&
3625                 echo "$BASHPID: link $tempfile to $1 succeeded"
3626         munlink $tempfile
3627 }
3628
3629 test_31o() { # LU-2901
3630         test_mkdir $DIR/$tdir
3631         for LOOP in $(seq 100); do
3632                 rm -f $DIR/$tdir/$tfile*
3633                 for THREAD in $(seq 8); do
3634                         link_one $DIR/$tdir/$tfile.$LOOP &
3635                 done
3636                 wait
3637                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3638                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3639                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3640                         break || true
3641         done
3642 }
3643 run_test 31o "duplicate hard links with same filename"
3644
3645 test_31p() {
3646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3647
3648         test_mkdir $DIR/$tdir
3649         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3650         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3651
3652         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3653                 error "open unlink test1 failed"
3654         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3655                 error "open unlink test2 failed"
3656
3657         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3658                 error "test1 still exists"
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3660                 error "test2 still exists"
3661 }
3662 run_test 31p "remove of open striped directory"
3663
3664 test_31q() {
3665         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3666
3667         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3668         index=$($LFS getdirstripe -i $DIR/$tdir)
3669         [ $index -eq 3 ] || error "first stripe index $index != 3"
3670         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3671         [ $index -eq 1 ] || error "second stripe index $index != 1"
3672
3673         # when "-c <stripe_count>" is set, the number of MDTs specified after
3674         # "-i" should equal to the stripe count
3675         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3676 }
3677 run_test 31q "create striped directory on specific MDTs"
3678
3679 cleanup_test32_mount() {
3680         local rc=0
3681         trap 0
3682         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3683         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3684         losetup -d $loopdev || true
3685         rm -rf $DIR/$tdir
3686         return $rc
3687 }
3688
3689 test_32a() {
3690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3691
3692         echo "== more mountpoints and symlinks ================="
3693         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3694         trap cleanup_test32_mount EXIT
3695         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3696         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3697                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3698         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3699                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3700         cleanup_test32_mount
3701 }
3702 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3703
3704 test_32b() {
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3708         trap cleanup_test32_mount EXIT
3709         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3710         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3711                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3712         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3713                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3714         cleanup_test32_mount
3715 }
3716 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3717
3718 test_32c() {
3719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3720
3721         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3722         trap cleanup_test32_mount EXIT
3723         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3724         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3725                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3726         test_mkdir -p $DIR/$tdir/d2/test_dir
3727         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3728                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3729         cleanup_test32_mount
3730 }
3731 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3732
3733 test_32d() {
3734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3735
3736         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3737         trap cleanup_test32_mount EXIT
3738         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3739         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3740                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3741         test_mkdir -p $DIR/$tdir/d2/test_dir
3742         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3743                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3744         cleanup_test32_mount
3745 }
3746 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3747
3748 test_32e() {
3749         rm -fr $DIR/$tdir
3750         test_mkdir -p $DIR/$tdir/tmp
3751         local tmp_dir=$DIR/$tdir/tmp
3752         ln -s $DIR/$tdir $tmp_dir/symlink11
3753         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3754         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3755         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3756 }
3757 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3758
3759 test_32f() {
3760         rm -fr $DIR/$tdir
3761         test_mkdir -p $DIR/$tdir/tmp
3762         local tmp_dir=$DIR/$tdir/tmp
3763         ln -s $DIR/$tdir $tmp_dir/symlink11
3764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3765         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3766         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3767 }
3768 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3769
3770 test_32g() {
3771         local tmp_dir=$DIR/$tdir/tmp
3772         test_mkdir -p $tmp_dir
3773         test_mkdir $DIR/${tdir}2
3774         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3775         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3776         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3777         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3778         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3779         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3780 }
3781 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3782
3783 test_32h() {
3784         rm -fr $DIR/$tdir $DIR/${tdir}2
3785         tmp_dir=$DIR/$tdir/tmp
3786         test_mkdir -p $tmp_dir
3787         test_mkdir $DIR/${tdir}2
3788         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3789         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3790         ls $tmp_dir/symlink12 || error "listing symlink12"
3791         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3792 }
3793 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3794
3795 test_32i() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         touch $DIR/$tdir/test_file
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3809
3810 test_32j() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         touch $DIR/$tdir/test_file
3819         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3820                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3821         cleanup_test32_mount
3822 }
3823 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3824
3825 test_32k() {
3826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3827
3828         rm -fr $DIR/$tdir
3829         trap cleanup_test32_mount EXIT
3830         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3831         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3832                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3833         test_mkdir -p $DIR/$tdir/d2
3834         touch $DIR/$tdir/d2/test_file || error "touch failed"
3835         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3836                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3837         cleanup_test32_mount
3838 }
3839 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3840
3841 test_32l() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2
3850         touch $DIR/$tdir/d2/test_file || error "touch failed"
3851         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3852                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3853         cleanup_test32_mount
3854 }
3855 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3856
3857 test_32m() {
3858         rm -fr $DIR/d32m
3859         test_mkdir -p $DIR/d32m/tmp
3860         TMP_DIR=$DIR/d32m/tmp
3861         ln -s $DIR $TMP_DIR/symlink11
3862         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3863         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3864                 error "symlink11 not a link"
3865         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3866                 error "symlink01 not a link"
3867 }
3868 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3869
3870 test_32n() {
3871         rm -fr $DIR/d32n
3872         test_mkdir -p $DIR/d32n/tmp
3873         TMP_DIR=$DIR/d32n/tmp
3874         ln -s $DIR $TMP_DIR/symlink11
3875         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3876         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3877         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3878 }
3879 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3880
3881 test_32o() {
3882         touch $DIR/$tfile
3883         test_mkdir -p $DIR/d32o/tmp
3884         TMP_DIR=$DIR/d32o/tmp
3885         ln -s $DIR/$tfile $TMP_DIR/symlink12
3886         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3887         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3888                 error "symlink12 not a link"
3889         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3890         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3891                 error "$DIR/d32o/tmp/symlink12 not file type"
3892         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3893                 error "$DIR/d32o/symlink02 not file type"
3894 }
3895 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3896
3897 test_32p() {
3898         log 32p_1
3899         rm -fr $DIR/d32p
3900         log 32p_2
3901         rm -f $DIR/$tfile
3902         log 32p_3
3903         touch $DIR/$tfile
3904         log 32p_4
3905         test_mkdir -p $DIR/d32p/tmp
3906         log 32p_5
3907         TMP_DIR=$DIR/d32p/tmp
3908         log 32p_6
3909         ln -s $DIR/$tfile $TMP_DIR/symlink12
3910         log 32p_7
3911         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3912         log 32p_8
3913         cat $DIR/d32p/tmp/symlink12 ||
3914                 error "Can't open $DIR/d32p/tmp/symlink12"
3915         log 32p_9
3916         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3917         log 32p_10
3918 }
3919 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3920
3921 test_32q() {
3922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3923
3924         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3925         trap cleanup_test32_mount EXIT
3926         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3927         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3928         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3929                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3930         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3931         cleanup_test32_mount
3932 }
3933 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3934
3935 test_32r() {
3936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3937
3938         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3939         trap cleanup_test32_mount EXIT
3940         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3941         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3942         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3943                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3944         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3945         cleanup_test32_mount
3946 }
3947 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3948
3949 test_33aa() {
3950         rm -f $DIR/$tfile
3951         touch $DIR/$tfile
3952         chmod 444 $DIR/$tfile
3953         chown $RUNAS_ID $DIR/$tfile
3954         log 33_1
3955         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3956         log 33_2
3957 }
3958 run_test 33aa "write file with mode 444 (should return error)"
3959
3960 test_33a() {
3961         rm -fr $DIR/$tdir
3962         test_mkdir $DIR/$tdir
3963         chown $RUNAS_ID $DIR/$tdir
3964         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3965                 error "$RUNAS create $tdir/$tfile failed"
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3967                 error "open RDWR" || true
3968 }
3969 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3970
3971 test_33b() {
3972         rm -fr $DIR/$tdir
3973         test_mkdir $DIR/$tdir
3974         chown $RUNAS_ID $DIR/$tdir
3975         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3976 }
3977 run_test 33b "test open file with malformed flags (No panic)"
3978
3979 test_33c() {
3980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3981         remote_ost_nodsh && skip "remote OST with nodsh"
3982
3983         local ostnum
3984         local ostname
3985         local write_bytes
3986         local all_zeros
3987
3988         all_zeros=true
3989         test_mkdir $DIR/$tdir
3990         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3991
3992         sync
3993         for ostnum in $(seq $OSTCOUNT); do
3994                 # test-framework's OST numbering is one-based, while Lustre's
3995                 # is zero-based
3996                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3997                 # check if at least some write_bytes stats are counted
3998                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3999                               obdfilter.$ostname.stats |
4000                               awk '/^write_bytes/ {print $7}' )
4001                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4002                 if (( ${write_bytes:-0} > 0 )); then
4003                         all_zeros=false
4004                         break
4005                 fi
4006         done
4007
4008         $all_zeros || return 0
4009
4010         # Write four bytes
4011         echo foo > $DIR/$tdir/bar
4012         # Really write them
4013         sync
4014
4015         # Total up write_bytes after writing.  We'd better find non-zeros.
4016         for ostnum in $(seq $OSTCOUNT); do
4017                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4018                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4019                               obdfilter/$ostname/stats |
4020                               awk '/^write_bytes/ {print $7}' )
4021                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4022                 if (( ${write_bytes:-0} > 0 )); then
4023                         all_zeros=false
4024                         break
4025                 fi
4026         done
4027
4028         if $all_zeros; then
4029                 for ostnum in $(seq $OSTCOUNT); do
4030                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4031                         echo "Check write_bytes is in obdfilter.*.stats:"
4032                         do_facet ost$ostnum lctl get_param -n \
4033                                 obdfilter.$ostname.stats
4034                 done
4035                 error "OST not keeping write_bytes stats (b=22312)"
4036         fi
4037 }
4038 run_test 33c "test write_bytes stats"
4039
4040 test_33d() {
4041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4043
4044         local MDTIDX=1
4045         local remote_dir=$DIR/$tdir/remote_dir
4046
4047         test_mkdir $DIR/$tdir
4048         $LFS mkdir -i $MDTIDX $remote_dir ||
4049                 error "create remote directory failed"
4050
4051         touch $remote_dir/$tfile
4052         chmod 444 $remote_dir/$tfile
4053         chown $RUNAS_ID $remote_dir/$tfile
4054
4055         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4056
4057         chown $RUNAS_ID $remote_dir
4058         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4059                                         error "create" || true
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4061                                     error "open RDWR" || true
4062         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4063 }
4064 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4065
4066 test_33e() {
4067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4068
4069         mkdir $DIR/$tdir
4070
4071         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4072         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4073         mkdir $DIR/$tdir/local_dir
4074
4075         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4076         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4077         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4078
4079         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4080                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4081
4082         rmdir $DIR/$tdir/* || error "rmdir failed"
4083
4084         umask 777
4085         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4086         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4087         mkdir $DIR/$tdir/local_dir
4088
4089         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4090         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4091         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4092
4093         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4094                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4095
4096         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4097
4098         umask 000
4099         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4100         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4101         mkdir $DIR/$tdir/local_dir
4102
4103         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4104         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4105         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4106
4107         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4108                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4109 }
4110 run_test 33e "mkdir and striped directory should have same mode"
4111
4112 cleanup_33f() {
4113         trap 0
4114         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4115 }
4116
4117 test_33f() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119         remote_mds_nodsh && skip "remote MDS with nodsh"
4120
4121         mkdir $DIR/$tdir
4122         chmod go+rwx $DIR/$tdir
4123         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4124         trap cleanup_33f EXIT
4125
4126         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4127                 error "cannot create striped directory"
4128
4129         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4130                 error "cannot create files in striped directory"
4131
4132         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4133                 error "cannot remove files in striped directory"
4134
4135         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4136                 error "cannot remove striped directory"
4137
4138         cleanup_33f
4139 }
4140 run_test 33f "nonroot user can create, access, and remove a striped directory"
4141
4142 test_33g() {
4143         mkdir -p $DIR/$tdir/dir2
4144
4145         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4146         echo $err
4147         [[ $err =~ "exists" ]] || error "Not exists error"
4148 }
4149 run_test 33g "nonroot user create already existing root created file"
4150
4151 test_33h() {
4152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4153         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4154                 skip "Need MDS version at least 2.13.50"
4155
4156         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4157                 error "mkdir $tdir failed"
4158         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4159
4160         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4161         local index2
4162
4163         for fname in $DIR/$tdir/$tfile.bak \
4164                      $DIR/$tdir/$tfile.SAV \
4165                      $DIR/$tdir/$tfile.orig \
4166                      $DIR/$tdir/$tfile~; do
4167                 touch $fname  || error "touch $fname failed"
4168                 index2=$($LFS getstripe -m $fname)
4169                 [ $index -eq $index2 ] ||
4170                         error "$fname MDT index mismatch $index != $index2"
4171         done
4172
4173         local failed=0
4174         for i in {1..250}; do
4175                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4176                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4177                         touch $fname  || error "touch $fname failed"
4178                         index2=$($LFS getstripe -m $fname)
4179                         if [[ $index != $index2 ]]; then
4180                                 failed=$((failed + 1))
4181                                 echo "$fname MDT index mismatch $index != $index2"
4182                         fi
4183                 done
4184         done
4185         echo "$failed MDT index mismatches"
4186         (( failed < 20 )) || error "MDT index mismatch $failed times"
4187
4188 }
4189 run_test 33h "temp file is located on the same MDT as target"
4190
4191 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4192 test_34a() {
4193         rm -f $DIR/f34
4194         $MCREATE $DIR/f34 || error "mcreate failed"
4195         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4196                 error "getstripe failed"
4197         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4198         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4199                 error "getstripe failed"
4200         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4201                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4202 }
4203 run_test 34a "truncate file that has not been opened ==========="
4204
4205 test_34b() {
4206         [ ! -f $DIR/f34 ] && test_34a
4207         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4208                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4209         $OPENFILE -f O_RDONLY $DIR/f34
4210         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4211                 error "getstripe failed"
4212         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4213                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4214 }
4215 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4216
4217 test_34c() {
4218         [ ! -f $DIR/f34 ] && test_34a
4219         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4220                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4221         $OPENFILE -f O_RDWR $DIR/f34
4222         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4223                 error "$LFS getstripe failed"
4224         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4225                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4226 }
4227 run_test 34c "O_RDWR opening file-with-size works =============="
4228
4229 test_34d() {
4230         [ ! -f $DIR/f34 ] && test_34a
4231         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4232                 error "dd failed"
4233         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4234                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4235         rm $DIR/f34
4236 }
4237 run_test 34d "write to sparse file ============================="
4238
4239 test_34e() {
4240         rm -f $DIR/f34e
4241         $MCREATE $DIR/f34e || error "mcreate failed"
4242         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4243         $CHECKSTAT -s 1000 $DIR/f34e ||
4244                 error "Size of $DIR/f34e not equal to 1000 bytes"
4245         $OPENFILE -f O_RDWR $DIR/f34e
4246         $CHECKSTAT -s 1000 $DIR/f34e ||
4247                 error "Size of $DIR/f34e not equal to 1000 bytes"
4248 }
4249 run_test 34e "create objects, some with size and some without =="
4250
4251 test_34f() { # bug 6242, 6243
4252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4253
4254         SIZE34F=48000
4255         rm -f $DIR/f34f
4256         $MCREATE $DIR/f34f || error "mcreate failed"
4257         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4258         dd if=$DIR/f34f of=$TMP/f34f
4259         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4260         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4261         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4262         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4263         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4264 }
4265 run_test 34f "read from a file with no objects until EOF ======="
4266
4267 test_34g() {
4268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4269
4270         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4271                 error "dd failed"
4272         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4273         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4274                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4275         cancel_lru_locks osc
4276         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4277                 error "wrong size after lock cancel"
4278
4279         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4280         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4281                 error "expanding truncate failed"
4282         cancel_lru_locks osc
4283         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4284                 error "wrong expanded size after lock cancel"
4285 }
4286 run_test 34g "truncate long file ==============================="
4287
4288 test_34h() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         local gid=10
4292         local sz=1000
4293
4294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4295         sync # Flush the cache so that multiop below does not block on cache
4296              # flush when getting the group lock
4297         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4298         MULTIPID=$!
4299
4300         # Since just timed wait is not good enough, let's do a sync write
4301         # that way we are sure enough time for a roundtrip + processing
4302         # passed + 2 seconds of extra margin.
4303         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4304         rm $DIR/${tfile}-1
4305         sleep 2
4306
4307         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4308                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4309                 kill -9 $MULTIPID
4310         fi
4311         wait $MULTIPID
4312         local nsz=`stat -c %s $DIR/$tfile`
4313         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4314 }
4315 run_test 34h "ftruncate file under grouplock should not block"
4316
4317 test_35a() {
4318         cp /bin/sh $DIR/f35a
4319         chmod 444 $DIR/f35a
4320         chown $RUNAS_ID $DIR/f35a
4321         $RUNAS $DIR/f35a && error || true
4322         rm $DIR/f35a
4323 }
4324 run_test 35a "exec file with mode 444 (should return and not leak)"
4325
4326 test_36a() {
4327         rm -f $DIR/f36
4328         utime $DIR/f36 || error "utime failed for MDS"
4329 }
4330 run_test 36a "MDS utime check (mknod, utime)"
4331
4332 test_36b() {
4333         echo "" > $DIR/f36
4334         utime $DIR/f36 || error "utime failed for OST"
4335 }
4336 run_test 36b "OST utime check (open, utime)"
4337
4338 test_36c() {
4339         rm -f $DIR/d36/f36
4340         test_mkdir $DIR/d36
4341         chown $RUNAS_ID $DIR/d36
4342         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4343 }
4344 run_test 36c "non-root MDS utime check (mknod, utime)"
4345
4346 test_36d() {
4347         [ ! -d $DIR/d36 ] && test_36c
4348         echo "" > $DIR/d36/f36
4349         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4350 }
4351 run_test 36d "non-root OST utime check (open, utime)"
4352
4353 test_36e() {
4354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4355
4356         test_mkdir $DIR/$tdir
4357         touch $DIR/$tdir/$tfile
4358         $RUNAS utime $DIR/$tdir/$tfile &&
4359                 error "utime worked, expected failure" || true
4360 }
4361 run_test 36e "utime on non-owned file (should return error)"
4362
4363 subr_36fh() {
4364         local fl="$1"
4365         local LANG_SAVE=$LANG
4366         local LC_LANG_SAVE=$LC_LANG
4367         export LANG=C LC_LANG=C # for date language
4368
4369         DATESTR="Dec 20  2000"
4370         test_mkdir $DIR/$tdir
4371         lctl set_param fail_loc=$fl
4372         date; date +%s
4373         cp /etc/hosts $DIR/$tdir/$tfile
4374         sync & # write RPC generated with "current" inode timestamp, but delayed
4375         sleep 1
4376         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4377         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4378         cancel_lru_locks $OSC
4379         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4380         date; date +%s
4381         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4382                 echo "BEFORE: $LS_BEFORE" && \
4383                 echo "AFTER : $LS_AFTER" && \
4384                 echo "WANT  : $DATESTR" && \
4385                 error "$DIR/$tdir/$tfile timestamps changed" || true
4386
4387         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4388 }
4389
4390 test_36f() {
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392
4393         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4394         subr_36fh "0x80000214"
4395 }
4396 run_test 36f "utime on file racing with OST BRW write =========="
4397
4398 test_36g() {
4399         remote_ost_nodsh && skip "remote OST with nodsh"
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4402                 skip "Need MDS version at least 2.12.51"
4403
4404         local fmd_max_age
4405         local fmd
4406         local facet="ost1"
4407         local tgt="obdfilter"
4408
4409         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4410
4411         test_mkdir $DIR/$tdir
4412         fmd_max_age=$(do_facet $facet \
4413                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4414                 head -n 1")
4415
4416         echo "FMD max age: ${fmd_max_age}s"
4417         touch $DIR/$tdir/$tfile
4418         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4419                 gawk '{cnt=cnt+$1}  END{print cnt}')
4420         echo "FMD before: $fmd"
4421         [[ $fmd == 0 ]] &&
4422                 error "FMD wasn't create by touch"
4423         sleep $((fmd_max_age + 12))
4424         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4425                 gawk '{cnt=cnt+$1}  END{print cnt}')
4426         echo "FMD after: $fmd"
4427         [[ $fmd == 0 ]] ||
4428                 error "FMD wasn't expired by ping"
4429 }
4430 run_test 36g "FMD cache expiry ====================="
4431
4432 test_36h() {
4433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4434
4435         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4436         subr_36fh "0x80000227"
4437 }
4438 run_test 36h "utime on file racing with OST BRW write =========="
4439
4440 test_36i() {
4441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4442
4443         test_mkdir $DIR/$tdir
4444         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4445
4446         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4447         local new_mtime=$((mtime + 200))
4448
4449         #change Modify time of striped dir
4450         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4451                         error "change mtime failed"
4452
4453         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4454
4455         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4456 }
4457 run_test 36i "change mtime on striped directory"
4458
4459 # test_37 - duplicate with tests 32q 32r
4460
4461 test_38() {
4462         local file=$DIR/$tfile
4463         touch $file
4464         openfile -f O_DIRECTORY $file
4465         local RC=$?
4466         local ENOTDIR=20
4467         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4468         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4469 }
4470 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4471
4472 test_39a() { # was test_39
4473         touch $DIR/$tfile
4474         touch $DIR/${tfile}2
4475 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4476 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4478         sleep 2
4479         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4480         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4481                 echo "mtime"
4482                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4483                 echo "atime"
4484                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "ctime"
4486                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4487                 error "O_TRUNC didn't change timestamps"
4488         fi
4489 }
4490 run_test 39a "mtime changed on create"
4491
4492 test_39b() {
4493         test_mkdir -c1 $DIR/$tdir
4494         cp -p /etc/passwd $DIR/$tdir/fopen
4495         cp -p /etc/passwd $DIR/$tdir/flink
4496         cp -p /etc/passwd $DIR/$tdir/funlink
4497         cp -p /etc/passwd $DIR/$tdir/frename
4498         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4499
4500         sleep 1
4501         echo "aaaaaa" >> $DIR/$tdir/fopen
4502         echo "aaaaaa" >> $DIR/$tdir/flink
4503         echo "aaaaaa" >> $DIR/$tdir/funlink
4504         echo "aaaaaa" >> $DIR/$tdir/frename
4505
4506         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4507         local link_new=`stat -c %Y $DIR/$tdir/flink`
4508         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4509         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4510
4511         cat $DIR/$tdir/fopen > /dev/null
4512         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4513         rm -f $DIR/$tdir/funlink2
4514         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4515
4516         for (( i=0; i < 2; i++ )) ; do
4517                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4518                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4519                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4520                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4521
4522                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4523                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4524                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4525                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4526
4527                 cancel_lru_locks $OSC
4528                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4529         done
4530 }
4531 run_test 39b "mtime change on open, link, unlink, rename  ======"
4532
4533 # this should be set to past
4534 TEST_39_MTIME=`date -d "1 year ago" +%s`
4535
4536 # bug 11063
4537 test_39c() {
4538         touch $DIR1/$tfile
4539         sleep 2
4540         local mtime0=`stat -c %Y $DIR1/$tfile`
4541
4542         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4543         local mtime1=`stat -c %Y $DIR1/$tfile`
4544         [ "$mtime1" = $TEST_39_MTIME ] || \
4545                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4546
4547         local d1=`date +%s`
4548         echo hello >> $DIR1/$tfile
4549         local d2=`date +%s`
4550         local mtime2=`stat -c %Y $DIR1/$tfile`
4551         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4552                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4553
4554         mv $DIR1/$tfile $DIR1/$tfile-1
4555
4556         for (( i=0; i < 2; i++ )) ; do
4557                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4558                 [ "$mtime2" = "$mtime3" ] || \
4559                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4560
4561                 cancel_lru_locks $OSC
4562                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4563         done
4564 }
4565 run_test 39c "mtime change on rename ==========================="
4566
4567 # bug 21114
4568 test_39d() {
4569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4570
4571         touch $DIR1/$tfile
4572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4573
4574         for (( i=0; i < 2; i++ )) ; do
4575                 local mtime=`stat -c %Y $DIR1/$tfile`
4576                 [ $mtime = $TEST_39_MTIME ] || \
4577                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4578
4579                 cancel_lru_locks $OSC
4580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4581         done
4582 }
4583 run_test 39d "create, utime, stat =============================="
4584
4585 # bug 21114
4586 test_39e() {
4587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4588
4589         touch $DIR1/$tfile
4590         local mtime1=`stat -c %Y $DIR1/$tfile`
4591
4592         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4593
4594         for (( i=0; i < 2; i++ )) ; do
4595                 local mtime2=`stat -c %Y $DIR1/$tfile`
4596                 [ $mtime2 = $TEST_39_MTIME ] || \
4597                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4598
4599                 cancel_lru_locks $OSC
4600                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4601         done
4602 }
4603 run_test 39e "create, stat, utime, stat ========================"
4604
4605 # bug 21114
4606 test_39f() {
4607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4608
4609         touch $DIR1/$tfile
4610         mtime1=`stat -c %Y $DIR1/$tfile`
4611
4612         sleep 2
4613         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4614
4615         for (( i=0; i < 2; i++ )) ; do
4616                 local mtime2=`stat -c %Y $DIR1/$tfile`
4617                 [ $mtime2 = $TEST_39_MTIME ] || \
4618                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4619
4620                 cancel_lru_locks $OSC
4621                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4622         done
4623 }
4624 run_test 39f "create, stat, sleep, utime, stat ================="
4625
4626 # bug 11063
4627 test_39g() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         sleep 2
4634         chmod o+r $DIR1/$tfile
4635
4636         for (( i=0; i < 2; i++ )) ; do
4637                 local mtime2=`stat -c %Y $DIR1/$tfile`
4638                 [ "$mtime1" = "$mtime2" ] || \
4639                         error "lost mtime: $mtime2, should be $mtime1"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39g "write, chmod, stat ==============================="
4646
4647 # bug 11063
4648 test_39h() {
4649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4650
4651         touch $DIR1/$tfile
4652         sleep 1
4653
4654         local d1=`date`
4655         echo hello >> $DIR1/$tfile
4656         local mtime1=`stat -c %Y $DIR1/$tfile`
4657
4658         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4659         local d2=`date`
4660         if [ "$d1" != "$d2" ]; then
4661                 echo "write and touch not within one second"
4662         else
4663                 for (( i=0; i < 2; i++ )) ; do
4664                         local mtime2=`stat -c %Y $DIR1/$tfile`
4665                         [ "$mtime2" = $TEST_39_MTIME ] || \
4666                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4667
4668                         cancel_lru_locks $OSC
4669                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4670                 done
4671         fi
4672 }
4673 run_test 39h "write, utime within one second, stat ============="
4674
4675 test_39i() {
4676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4677
4678         touch $DIR1/$tfile
4679         sleep 1
4680
4681         echo hello >> $DIR1/$tfile
4682         local mtime1=`stat -c %Y $DIR1/$tfile`
4683
4684         mv $DIR1/$tfile $DIR1/$tfile-1
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688
4689                 [ "$mtime1" = "$mtime2" ] || \
4690                         error "lost mtime: $mtime2, should be $mtime1"
4691
4692                 cancel_lru_locks $OSC
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695 }
4696 run_test 39i "write, rename, stat =============================="
4697
4698 test_39j() {
4699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4700
4701         start_full_debug_logging
4702         touch $DIR1/$tfile
4703         sleep 1
4704
4705         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4706         lctl set_param fail_loc=0x80000412
4707         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4708                 error "multiop failed"
4709         local multipid=$!
4710         local mtime1=`stat -c %Y $DIR1/$tfile`
4711
4712         mv $DIR1/$tfile $DIR1/$tfile-1
4713
4714         kill -USR1 $multipid
4715         wait $multipid || error "multiop close failed"
4716
4717         for (( i=0; i < 2; i++ )) ; do
4718                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4719                 [ "$mtime1" = "$mtime2" ] ||
4720                         error "mtime is lost on close: $mtime2, " \
4721                               "should be $mtime1"
4722
4723                 cancel_lru_locks
4724                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4725         done
4726         lctl set_param fail_loc=0
4727         stop_full_debug_logging
4728 }
4729 run_test 39j "write, rename, close, stat ======================="
4730
4731 test_39k() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         touch $DIR1/$tfile
4735         sleep 1
4736
4737         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4738         local multipid=$!
4739         local mtime1=`stat -c %Y $DIR1/$tfile`
4740
4741         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4742
4743         kill -USR1 $multipid
4744         wait $multipid || error "multiop close failed"
4745
4746         for (( i=0; i < 2; i++ )) ; do
4747                 local mtime2=`stat -c %Y $DIR1/$tfile`
4748
4749                 [ "$mtime2" = $TEST_39_MTIME ] || \
4750                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4751
4752                 cancel_lru_locks
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39k "write, utime, close, stat ========================"
4757
4758 # this should be set to future
4759 TEST_39_ATIME=`date -d "1 year" +%s`
4760
4761 test_39l() {
4762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4763         remote_mds_nodsh && skip "remote MDS with nodsh"
4764
4765         local atime_diff=$(do_facet $SINGLEMDS \
4766                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4767         rm -rf $DIR/$tdir
4768         mkdir -p $DIR/$tdir
4769
4770         # test setting directory atime to future
4771         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4772         local atime=$(stat -c %X $DIR/$tdir)
4773         [ "$atime" = $TEST_39_ATIME ] ||
4774                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4775
4776         # test setting directory atime from future to now
4777         local now=$(date +%s)
4778         touch -a -d @$now $DIR/$tdir
4779
4780         atime=$(stat -c %X $DIR/$tdir)
4781         [ "$atime" -eq "$now"  ] ||
4782                 error "atime is not updated from future: $atime, $now"
4783
4784         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4785         sleep 3
4786
4787         # test setting directory atime when now > dir atime + atime_diff
4788         local d1=$(date +%s)
4789         ls $DIR/$tdir
4790         local d2=$(date +%s)
4791         cancel_lru_locks mdc
4792         atime=$(stat -c %X $DIR/$tdir)
4793         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4794                 error "atime is not updated  : $atime, should be $d2"
4795
4796         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4797         sleep 3
4798
4799         # test not setting directory atime when now < dir atime + atime_diff
4800         ls $DIR/$tdir
4801         cancel_lru_locks mdc
4802         atime=$(stat -c %X $DIR/$tdir)
4803         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4804                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4805
4806         do_facet $SINGLEMDS \
4807                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4808 }
4809 run_test 39l "directory atime update ==========================="
4810
4811 test_39m() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         touch $DIR1/$tfile
4815         sleep 2
4816         local far_past_mtime=$(date -d "May 29 1953" +%s)
4817         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4818
4819         touch -m -d @$far_past_mtime $DIR1/$tfile
4820         touch -a -d @$far_past_atime $DIR1/$tfile
4821
4822         for (( i=0; i < 2; i++ )) ; do
4823                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4824                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4825                         error "atime or mtime set incorrectly"
4826
4827                 cancel_lru_locks $OSC
4828                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4829         done
4830 }
4831 run_test 39m "test atime and mtime before 1970"
4832
4833 test_39n() { # LU-3832
4834         remote_mds_nodsh && skip "remote MDS with nodsh"
4835
4836         local atime_diff=$(do_facet $SINGLEMDS \
4837                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4838         local atime0
4839         local atime1
4840         local atime2
4841
4842         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4843
4844         rm -rf $DIR/$tfile
4845         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4846         atime0=$(stat -c %X $DIR/$tfile)
4847
4848         sleep 5
4849         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4850         atime1=$(stat -c %X $DIR/$tfile)
4851
4852         sleep 5
4853         cancel_lru_locks mdc
4854         cancel_lru_locks osc
4855         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4856         atime2=$(stat -c %X $DIR/$tfile)
4857
4858         do_facet $SINGLEMDS \
4859                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4860
4861         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4862         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4863 }
4864 run_test 39n "check that O_NOATIME is honored"
4865
4866 test_39o() {
4867         TESTDIR=$DIR/$tdir/$tfile
4868         [ -e $TESTDIR ] && rm -rf $TESTDIR
4869         mkdir -p $TESTDIR
4870         cd $TESTDIR
4871         links1=2
4872         ls
4873         mkdir a b
4874         ls
4875         links2=$(stat -c %h .)
4876         [ $(($links1 + 2)) != $links2 ] &&
4877                 error "wrong links count $(($links1 + 2)) != $links2"
4878         rmdir b
4879         links3=$(stat -c %h .)
4880         [ $(($links1 + 1)) != $links3 ] &&
4881                 error "wrong links count $links1 != $links3"
4882         return 0
4883 }
4884 run_test 39o "directory cached attributes updated after create"
4885
4886 test_39p() {
4887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4888
4889         local MDTIDX=1
4890         TESTDIR=$DIR/$tdir/$tdir
4891         [ -e $TESTDIR ] && rm -rf $TESTDIR
4892         test_mkdir -p $TESTDIR
4893         cd $TESTDIR
4894         links1=2
4895         ls
4896         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4898         ls
4899         links2=$(stat -c %h .)
4900         [ $(($links1 + 2)) != $links2 ] &&
4901                 error "wrong links count $(($links1 + 2)) != $links2"
4902         rmdir remote_dir2
4903         links3=$(stat -c %h .)
4904         [ $(($links1 + 1)) != $links3 ] &&
4905                 error "wrong links count $links1 != $links3"
4906         return 0
4907 }
4908 run_test 39p "remote directory cached attributes updated after create ========"
4909
4910 test_39r() {
4911         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4912                 skip "no atime update on old OST"
4913         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4914                 skip_env "ldiskfs only test"
4915         fi
4916
4917         local saved_adiff
4918         saved_adiff=$(do_facet ost1 \
4919                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4920         stack_trap "do_facet ost1 \
4921                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4922
4923         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4924
4925         $LFS setstripe -i 0 $DIR/$tfile
4926         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4927                 error "can't write initial file"
4928         cancel_lru_locks osc
4929
4930         # exceed atime_diff and access file
4931         sleep 6
4932         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4933                 error "can't udpate atime"
4934
4935         local atime_cli=$(stat -c %X $DIR/$tfile)
4936         echo "client atime: $atime_cli"
4937         # allow atime update to be written to device
4938         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4939         sleep 5
4940
4941         local ostdev=$(ostdevname 1)
4942         local fid=($(lfs getstripe -y $DIR/$tfile |
4943                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4944         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4945         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4946
4947         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4948         local atime_ost=$(do_facet ost1 "$cmd" |&
4949                           awk -F'[: ]' '/atime:/ { print $4 }')
4950         (( atime_cli == atime_ost )) ||
4951                 error "atime on client $atime_cli != ost $atime_ost"
4952 }
4953 run_test 39r "lazy atime update on OST"
4954
4955 test_39q() { # LU-8041
4956         local testdir=$DIR/$tdir
4957         mkdir -p $testdir
4958         multiop_bg_pause $testdir D_c || error "multiop failed"
4959         local multipid=$!
4960         cancel_lru_locks mdc
4961         kill -USR1 $multipid
4962         local atime=$(stat -c %X $testdir)
4963         [ "$atime" -ne 0 ] || error "atime is zero"
4964 }
4965 run_test 39q "close won't zero out atime"
4966
4967 test_40() {
4968         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4969         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4970                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4971         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4972                 error "$tfile is not 4096 bytes in size"
4973 }
4974 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4975
4976 test_41() {
4977         # bug 1553
4978         small_write $DIR/f41 18
4979 }
4980 run_test 41 "test small file write + fstat ====================="
4981
4982 count_ost_writes() {
4983         lctl get_param -n ${OSC}.*.stats |
4984                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4985                         END { printf("%0.0f", writes) }'
4986 }
4987
4988 # decent default
4989 WRITEBACK_SAVE=500
4990 DIRTY_RATIO_SAVE=40
4991 MAX_DIRTY_RATIO=50
4992 BG_DIRTY_RATIO_SAVE=10
4993 MAX_BG_DIRTY_RATIO=25
4994
4995 start_writeback() {
4996         trap 0
4997         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4998         # dirty_ratio, dirty_background_ratio
4999         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5000                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5001                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5002                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5003         else
5004                 # if file not here, we are a 2.4 kernel
5005                 kill -CONT `pidof kupdated`
5006         fi
5007 }
5008
5009 stop_writeback() {
5010         # setup the trap first, so someone cannot exit the test at the
5011         # exact wrong time and mess up a machine
5012         trap start_writeback EXIT
5013         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5014         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5015                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5016                 sysctl -w vm.dirty_writeback_centisecs=0
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 # save and increase /proc/sys/vm/dirty_ratio
5019                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5020                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5021                 # save and increase /proc/sys/vm/dirty_background_ratio
5022                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5023                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5024         else
5025                 # if file not here, we are a 2.4 kernel
5026                 kill -STOP `pidof kupdated`
5027         fi
5028 }
5029
5030 # ensure that all stripes have some grant before we test client-side cache
5031 setup_test42() {
5032         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5033                 dd if=/dev/zero of=$i bs=4k count=1
5034                 rm $i
5035         done
5036 }
5037
5038 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5039 # file truncation, and file removal.
5040 test_42a() {
5041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5042
5043         setup_test42
5044         cancel_lru_locks $OSC
5045         stop_writeback
5046         sync; sleep 1; sync # just to be safe
5047         BEFOREWRITES=`count_ost_writes`
5048         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5049         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5050         AFTERWRITES=`count_ost_writes`
5051         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5052                 error "$BEFOREWRITES < $AFTERWRITES"
5053         start_writeback
5054 }
5055 run_test 42a "ensure that we don't flush on close"
5056
5057 test_42b() {
5058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5059
5060         setup_test42
5061         cancel_lru_locks $OSC
5062         stop_writeback
5063         sync
5064         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5065         BEFOREWRITES=$(count_ost_writes)
5066         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5067         AFTERWRITES=$(count_ost_writes)
5068         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5069                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5070         fi
5071         BEFOREWRITES=$(count_ost_writes)
5072         sync || error "sync: $?"
5073         AFTERWRITES=$(count_ost_writes)
5074         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5075                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5076         fi
5077         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5078         start_writeback
5079         return 0
5080 }
5081 run_test 42b "test destroy of file with cached dirty data ======"
5082
5083 # if these tests just want to test the effect of truncation,
5084 # they have to be very careful.  consider:
5085 # - the first open gets a {0,EOF}PR lock
5086 # - the first write conflicts and gets a {0, count-1}PW
5087 # - the rest of the writes are under {count,EOF}PW
5088 # - the open for truncate tries to match a {0,EOF}PR
5089 #   for the filesize and cancels the PWs.
5090 # any number of fixes (don't get {0,EOF} on open, match
5091 # composite locks, do smarter file size management) fix
5092 # this, but for now we want these tests to verify that
5093 # the cancellation with truncate intent works, so we
5094 # start the file with a full-file pw lock to match against
5095 # until the truncate.
5096 trunc_test() {
5097         test=$1
5098         file=$DIR/$test
5099         offset=$2
5100         cancel_lru_locks $OSC
5101         stop_writeback
5102         # prime the file with 0,EOF PW to match
5103         touch $file
5104         $TRUNCATE $file 0
5105         sync; sync
5106         # now the real test..
5107         dd if=/dev/zero of=$file bs=1024 count=100
5108         BEFOREWRITES=`count_ost_writes`
5109         $TRUNCATE $file $offset
5110         cancel_lru_locks $OSC
5111         AFTERWRITES=`count_ost_writes`
5112         start_writeback
5113 }
5114
5115 test_42c() {
5116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5117
5118         trunc_test 42c 1024
5119         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5120                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5121         rm $file
5122 }
5123 run_test 42c "test partial truncate of file with cached dirty data"
5124
5125 test_42d() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         trunc_test 42d 0
5129         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5130                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5131         rm $file
5132 }
5133 run_test 42d "test complete truncate of file with cached dirty data"
5134
5135 test_42e() { # bug22074
5136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5137
5138         local TDIR=$DIR/${tdir}e
5139         local pages=16 # hardcoded 16 pages, don't change it.
5140         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5141         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5142         local max_dirty_mb
5143         local warmup_files
5144
5145         test_mkdir $DIR/${tdir}e
5146         $LFS setstripe -c 1 $TDIR
5147         createmany -o $TDIR/f $files
5148
5149         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5150
5151         # we assume that with $OSTCOUNT files, at least one of them will
5152         # be allocated on OST0.
5153         warmup_files=$((OSTCOUNT * max_dirty_mb))
5154         createmany -o $TDIR/w $warmup_files
5155
5156         # write a large amount of data into one file and sync, to get good
5157         # avail_grant number from OST.
5158         for ((i=0; i<$warmup_files; i++)); do
5159                 idx=$($LFS getstripe -i $TDIR/w$i)
5160                 [ $idx -ne 0 ] && continue
5161                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5162                 break
5163         done
5164         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5165         sync
5166         $LCTL get_param $proc_osc0/cur_dirty_bytes
5167         $LCTL get_param $proc_osc0/cur_grant_bytes
5168
5169         # create as much dirty pages as we can while not to trigger the actual
5170         # RPCs directly. but depends on the env, VFS may trigger flush during this
5171         # period, hopefully we are good.
5172         for ((i=0; i<$warmup_files; i++)); do
5173                 idx=$($LFS getstripe -i $TDIR/w$i)
5174                 [ $idx -ne 0 ] && continue
5175                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5176         done
5177         $LCTL get_param $proc_osc0/cur_dirty_bytes
5178         $LCTL get_param $proc_osc0/cur_grant_bytes
5179
5180         # perform the real test
5181         $LCTL set_param $proc_osc0/rpc_stats 0
5182         for ((;i<$files; i++)); do
5183                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5184                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5185         done
5186         sync
5187         $LCTL get_param $proc_osc0/rpc_stats
5188
5189         local percent=0
5190         local have_ppr=false
5191         $LCTL get_param $proc_osc0/rpc_stats |
5192                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5193                         # skip lines until we are at the RPC histogram data
5194                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5195                         $have_ppr || continue
5196
5197                         # we only want the percent stat for < 16 pages
5198                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5199
5200                         percent=$((percent + WPCT))
5201                         if [[ $percent -gt 15 ]]; then
5202                                 error "less than 16-pages write RPCs" \
5203                                       "$percent% > 15%"
5204                                 break
5205                         fi
5206                 done
5207         rm -rf $TDIR
5208 }
5209 run_test 42e "verify sub-RPC writes are not done synchronously"
5210
5211 test_43A() { # was test_43
5212         test_mkdir $DIR/$tdir
5213         cp -p /bin/ls $DIR/$tdir/$tfile
5214         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5215         pid=$!
5216         # give multiop a chance to open
5217         sleep 1
5218
5219         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5220         kill -USR1 $pid
5221         # Wait for multiop to exit
5222         wait $pid
5223 }
5224 run_test 43A "execution of file opened for write should return -ETXTBSY"
5225
5226 test_43a() {
5227         test_mkdir $DIR/$tdir
5228         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5229         $DIR/$tdir/sleep 60 &
5230         SLEEP_PID=$!
5231         # Make sure exec of $tdir/sleep wins race with truncate
5232         sleep 1
5233         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5234         kill $SLEEP_PID
5235 }
5236 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5237
5238 test_43b() {
5239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5240
5241         test_mkdir $DIR/$tdir
5242         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5243         $DIR/$tdir/sleep 60 &
5244         SLEEP_PID=$!
5245         # Make sure exec of $tdir/sleep wins race with truncate
5246         sleep 1
5247         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5248         kill $SLEEP_PID
5249 }
5250 run_test 43b "truncate of file being executed should return -ETXTBSY"
5251
5252 test_43c() {
5253         local testdir="$DIR/$tdir"
5254         test_mkdir $testdir
5255         cp $SHELL $testdir/
5256         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5257                 ( cd $testdir && md5sum -c )
5258 }
5259 run_test 43c "md5sum of copy into lustre"
5260
5261 test_44A() { # was test_44
5262         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5263
5264         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5265         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5266 }
5267 run_test 44A "zero length read from a sparse stripe"
5268
5269 test_44a() {
5270         local nstripe=$($LFS getstripe -c -d $DIR)
5271         [ -z "$nstripe" ] && skip "can't get stripe info"
5272         [[ $nstripe -gt $OSTCOUNT ]] &&
5273                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5274
5275         local stride=$($LFS getstripe -S -d $DIR)
5276         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5277                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5278         fi
5279
5280         OFFSETS="0 $((stride/2)) $((stride-1))"
5281         for offset in $OFFSETS; do
5282                 for i in $(seq 0 $((nstripe-1))); do
5283                         local GLOBALOFFSETS=""
5284                         # size in Bytes
5285                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5286                         local myfn=$DIR/d44a-$size
5287                         echo "--------writing $myfn at $size"
5288                         ll_sparseness_write $myfn $size ||
5289                                 error "ll_sparseness_write"
5290                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5291                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5292                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5293
5294                         for j in $(seq 0 $((nstripe-1))); do
5295                                 # size in Bytes
5296                                 size=$((((j + $nstripe )*$stride + $offset)))
5297                                 ll_sparseness_write $myfn $size ||
5298                                         error "ll_sparseness_write"
5299                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5300                         done
5301                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5302                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5303                         rm -f $myfn
5304                 done
5305         done
5306 }
5307 run_test 44a "test sparse pwrite ==============================="
5308
5309 dirty_osc_total() {
5310         tot=0
5311         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5312                 tot=$(($tot + $d))
5313         done
5314         echo $tot
5315 }
5316 do_dirty_record() {
5317         before=`dirty_osc_total`
5318         echo executing "\"$*\""
5319         eval $*
5320         after=`dirty_osc_total`
5321         echo before $before, after $after
5322 }
5323 test_45() {
5324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5325
5326         f="$DIR/f45"
5327         # Obtain grants from OST if it supports it
5328         echo blah > ${f}_grant
5329         stop_writeback
5330         sync
5331         do_dirty_record "echo blah > $f"
5332         [[ $before -eq $after ]] && error "write wasn't cached"
5333         do_dirty_record "> $f"
5334         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5335         do_dirty_record "echo blah > $f"
5336         [[ $before -eq $after ]] && error "write wasn't cached"
5337         do_dirty_record "sync"
5338         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5339         do_dirty_record "echo blah > $f"
5340         [[ $before -eq $after ]] && error "write wasn't cached"
5341         do_dirty_record "cancel_lru_locks osc"
5342         [[ $before -gt $after ]] ||
5343                 error "lock cancellation didn't lower dirty count"
5344         start_writeback
5345 }
5346 run_test 45 "osc io page accounting ============================"
5347
5348 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5349 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5350 # objects offset and an assert hit when an rpc was built with 1023's mapped
5351 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5352 test_46() {
5353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5354
5355         f="$DIR/f46"
5356         stop_writeback
5357         sync
5358         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5359         sync
5360         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5362         sync
5363         start_writeback
5364 }
5365 run_test 46 "dirtying a previously written page ================"
5366
5367 # test_47 is removed "Device nodes check" is moved to test_28
5368
5369 test_48a() { # bug 2399
5370         [ "$mds1_FSTYPE" = "zfs" ] &&
5371         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5372                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5373
5374         test_mkdir $DIR/$tdir
5375         cd $DIR/$tdir
5376         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5377         test_mkdir $DIR/$tdir
5378         touch foo || error "'touch foo' failed after recreating cwd"
5379         test_mkdir bar
5380         touch .foo || error "'touch .foo' failed after recreating cwd"
5381         test_mkdir .bar
5382         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5383         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5384         cd . || error "'cd .' failed after recreating cwd"
5385         mkdir . && error "'mkdir .' worked after recreating cwd"
5386         rmdir . && error "'rmdir .' worked after recreating cwd"
5387         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5388         cd .. || error "'cd ..' failed after recreating cwd"
5389 }
5390 run_test 48a "Access renamed working dir (should return errors)="
5391
5392 test_48b() { # bug 2399
5393         rm -rf $DIR/$tdir
5394         test_mkdir $DIR/$tdir
5395         cd $DIR/$tdir
5396         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5397         touch foo && error "'touch foo' worked after removing cwd"
5398         mkdir foo && error "'mkdir foo' worked after removing cwd"
5399         touch .foo && error "'touch .foo' worked after removing cwd"
5400         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5401         ls . > /dev/null && error "'ls .' worked after removing cwd"
5402         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5403         mkdir . && error "'mkdir .' worked after removing cwd"
5404         rmdir . && error "'rmdir .' worked after removing cwd"
5405         ln -s . foo && error "'ln -s .' worked after removing cwd"
5406         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5407 }
5408 run_test 48b "Access removed working dir (should return errors)="
5409
5410 test_48c() { # bug 2350
5411         #lctl set_param debug=-1
5412         #set -vx
5413         rm -rf $DIR/$tdir
5414         test_mkdir -p $DIR/$tdir/dir
5415         cd $DIR/$tdir/dir
5416         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5417         $TRACE touch foo && error "touch foo worked after removing cwd"
5418         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5419         touch .foo && error "touch .foo worked after removing cwd"
5420         mkdir .foo && error "mkdir .foo worked after removing cwd"
5421         $TRACE ls . && error "'ls .' worked after removing cwd"
5422         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5423         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5424         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5425         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5426         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5427 }
5428 run_test 48c "Access removed working subdir (should return errors)"
5429
5430 test_48d() { # bug 2350
5431         #lctl set_param debug=-1
5432         #set -vx
5433         rm -rf $DIR/$tdir
5434         test_mkdir -p $DIR/$tdir/dir
5435         cd $DIR/$tdir/dir
5436         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5437         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5438         $TRACE touch foo && error "'touch foo' worked after removing parent"
5439         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5440         touch .foo && error "'touch .foo' worked after removing parent"
5441         mkdir .foo && error "mkdir .foo worked after removing parent"
5442         $TRACE ls . && error "'ls .' worked after removing parent"
5443         $TRACE ls .. && error "'ls ..' worked after removing parent"
5444         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5445         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5446         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5447         true
5448 }
5449 run_test 48d "Access removed parent subdir (should return errors)"
5450
5451 test_48e() { # bug 4134
5452         #lctl set_param debug=-1
5453         #set -vx
5454         rm -rf $DIR/$tdir
5455         test_mkdir -p $DIR/$tdir/dir
5456         cd $DIR/$tdir/dir
5457         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5458         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5459         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5460         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5461         # On a buggy kernel addition of "touch foo" after cd .. will
5462         # produce kernel oops in lookup_hash_it
5463         touch ../foo && error "'cd ..' worked after recreate parent"
5464         cd $DIR
5465         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5466 }
5467 run_test 48e "Access to recreated parent subdir (should return errors)"
5468
5469 test_48f() {
5470         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5471                 skip "need MDS >= 2.13.55"
5472         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5473         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5474                 skip "needs different host for mdt1 mdt2"
5475         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5476
5477         $LFS mkdir -i0 $DIR/$tdir
5478         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5479
5480         for d in sub1 sub2 sub3; do
5481                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5482                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5483                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5484         done
5485
5486         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5487 }
5488 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5489
5490 test_49() { # LU-1030
5491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5492         remote_ost_nodsh && skip "remote OST with nodsh"
5493
5494         # get ost1 size - $FSNAME-OST0000
5495         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5496                 awk '{ print $4 }')
5497         # write 800M at maximum
5498         [[ $ost1_size -lt 2 ]] && ost1_size=2
5499         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5500
5501         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5502         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5503         local dd_pid=$!
5504
5505         # change max_pages_per_rpc while writing the file
5506         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5507         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5508         # loop until dd process exits
5509         while ps ax -opid | grep -wq $dd_pid; do
5510                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5511                 sleep $((RANDOM % 5 + 1))
5512         done
5513         # restore original max_pages_per_rpc
5514         $LCTL set_param $osc1_mppc=$orig_mppc
5515         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5516 }
5517 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5518
5519 test_50() {
5520         # bug 1485
5521         test_mkdir $DIR/$tdir
5522         cd $DIR/$tdir
5523         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5524 }
5525 run_test 50 "special situations: /proc symlinks  ==============="
5526
5527 test_51a() {    # was test_51
5528         # bug 1516 - create an empty entry right after ".." then split dir
5529         test_mkdir -c1 $DIR/$tdir
5530         touch $DIR/$tdir/foo
5531         $MCREATE $DIR/$tdir/bar
5532         rm $DIR/$tdir/foo
5533         createmany -m $DIR/$tdir/longfile 201
5534         FNUM=202
5535         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5536                 $MCREATE $DIR/$tdir/longfile$FNUM
5537                 FNUM=$(($FNUM + 1))
5538                 echo -n "+"
5539         done
5540         echo
5541         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5542 }
5543 run_test 51a "special situations: split htree with empty entry =="
5544
5545 cleanup_print_lfs_df () {
5546         trap 0
5547         $LFS df
5548         $LFS df -i
5549 }
5550
5551 test_51b() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         local dir=$DIR/$tdir
5555         local nrdirs=$((65536 + 100))
5556
5557         # cleanup the directory
5558         rm -fr $dir
5559
5560         test_mkdir -c1 $dir
5561
5562         $LFS df
5563         $LFS df -i
5564         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5565         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5566         [[ $numfree -lt $nrdirs ]] &&
5567                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5568
5569         # need to check free space for the directories as well
5570         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5571         numfree=$(( blkfree / $(fs_inode_ksize) ))
5572         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5573
5574         trap cleanup_print_lfs_df EXIT
5575
5576         # create files
5577         createmany -d $dir/d $nrdirs || {
5578                 unlinkmany $dir/d $nrdirs
5579                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5580         }
5581
5582         # really created :
5583         nrdirs=$(ls -U $dir | wc -l)
5584
5585         # unlink all but 100 subdirectories, then check it still works
5586         local left=100
5587         local delete=$((nrdirs - left))
5588
5589         $LFS df
5590         $LFS df -i
5591
5592         # for ldiskfs the nlink count should be 1, but this is OSD specific
5593         # and so this is listed for informational purposes only
5594         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5595         unlinkmany -d $dir/d $delete ||
5596                 error "unlink of first $delete subdirs failed"
5597
5598         echo "nlink between: $(stat -c %h $dir)"
5599         local found=$(ls -U $dir | wc -l)
5600         [ $found -ne $left ] &&
5601                 error "can't find subdirs: found only $found, expected $left"
5602
5603         unlinkmany -d $dir/d $delete $left ||
5604                 error "unlink of second $left subdirs failed"
5605         # regardless of whether the backing filesystem tracks nlink accurately
5606         # or not, the nlink count shouldn't be more than "." and ".." here
5607         local after=$(stat -c %h $dir)
5608         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5609                 echo "nlink after: $after"
5610
5611         cleanup_print_lfs_df
5612 }
5613 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5614
5615 test_51d() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5618
5619         test_mkdir $DIR/$tdir
5620         createmany -o $DIR/$tdir/t- 1000
5621         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5622         for N in $(seq 0 $((OSTCOUNT - 1))); do
5623                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5624                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5625                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5626                         '($1 == '$N') { objs += 1 } \
5627                         END { printf("%0.0f", objs) }')
5628                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5629         done
5630         unlinkmany $DIR/$tdir/t- 1000
5631
5632         NLAST=0
5633         for N in $(seq 1 $((OSTCOUNT - 1))); do
5634                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5635                         error "OST $N has less objects vs OST $NLAST" \
5636                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5637                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5638                         error "OST $N has less objects vs OST $NLAST" \
5639                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5640
5641                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5642                         error "OST $N has less #0 objects vs OST $NLAST" \
5643                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5644                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5645                         error "OST $N has less #0 objects vs OST $NLAST" \
5646                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5647                 NLAST=$N
5648         done
5649         rm -f $TMP/$tfile
5650 }
5651 run_test 51d "check object distribution"
5652
5653 test_51e() {
5654         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5655                 skip_env "ldiskfs only test"
5656         fi
5657
5658         test_mkdir -c1 $DIR/$tdir
5659         test_mkdir -c1 $DIR/$tdir/d0
5660
5661         touch $DIR/$tdir/d0/foo
5662         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5663                 error "file exceed 65000 nlink limit!"
5664         unlinkmany $DIR/$tdir/d0/f- 65001
5665         return 0
5666 }
5667 run_test 51e "check file nlink limit"
5668
5669 test_51f() {
5670         test_mkdir $DIR/$tdir
5671
5672         local max=100000
5673         local ulimit_old=$(ulimit -n)
5674         local spare=20 # number of spare fd's for scripts/libraries, etc.
5675         local mdt=$($LFS getstripe -m $DIR/$tdir)
5676         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5677
5678         echo "MDT$mdt numfree=$numfree, max=$max"
5679         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5680         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5681                 while ! ulimit -n $((numfree + spare)); do
5682                         numfree=$((numfree * 3 / 4))
5683                 done
5684                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5685         else
5686                 echo "left ulimit at $ulimit_old"
5687         fi
5688
5689         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5690                 unlinkmany $DIR/$tdir/f $numfree
5691                 error "create+open $numfree files in $DIR/$tdir failed"
5692         }
5693         ulimit -n $ulimit_old
5694
5695         # if createmany exits at 120s there will be fewer than $numfree files
5696         unlinkmany $DIR/$tdir/f $numfree || true
5697 }
5698 run_test 51f "check many open files limit"
5699
5700 test_52a() {
5701         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5702         test_mkdir $DIR/$tdir
5703         touch $DIR/$tdir/foo
5704         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5705         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5706         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5707         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5708         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5709                                         error "link worked"
5710         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5711         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5712         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5713                                                      error "lsattr"
5714         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5715         cp -r $DIR/$tdir $TMP/
5716         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5717 }
5718 run_test 52a "append-only flag test (should return errors)"
5719
5720 test_52b() {
5721         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5722         test_mkdir $DIR/$tdir
5723         touch $DIR/$tdir/foo
5724         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5725         cat test > $DIR/$tdir/foo && error "cat test worked"
5726         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5727         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5728         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5729                                         error "link worked"
5730         echo foo >> $DIR/$tdir/foo && error "echo worked"
5731         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5732         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5733         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5734         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5735                                                         error "lsattr"
5736         chattr -i $DIR/$tdir/foo || error "chattr failed"
5737
5738         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5739 }
5740 run_test 52b "immutable flag test (should return errors) ======="
5741
5742 test_53() {
5743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5744         remote_mds_nodsh && skip "remote MDS with nodsh"
5745         remote_ost_nodsh && skip "remote OST with nodsh"
5746
5747         local param
5748         local param_seq
5749         local ostname
5750         local mds_last
5751         local mds_last_seq
5752         local ost_last
5753         local ost_last_seq
5754         local ost_last_id
5755         local ostnum
5756         local node
5757         local found=false
5758         local support_last_seq=true
5759
5760         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5761                 support_last_seq=false
5762
5763         # only test MDT0000
5764         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5765         local value
5766         for value in $(do_facet $SINGLEMDS \
5767                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5768                 param=$(echo ${value[0]} | cut -d "=" -f1)
5769                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5770
5771                 if $support_last_seq; then
5772                         param_seq=$(echo $param |
5773                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5774                         mds_last_seq=$(do_facet $SINGLEMDS \
5775                                        $LCTL get_param -n $param_seq)
5776                 fi
5777                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5778
5779                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5780                 node=$(facet_active_host ost$((ostnum+1)))
5781                 param="obdfilter.$ostname.last_id"
5782                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5783                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5784                         ost_last_id=$ost_last
5785
5786                         if $support_last_seq; then
5787                                 ost_last_id=$(echo $ost_last |
5788                                               awk -F':' '{print $2}' |
5789                                               sed -e "s/^0x//g")
5790                                 ost_last_seq=$(echo $ost_last |
5791                                                awk -F':' '{print $1}')
5792                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5793                         fi
5794
5795                         if [[ $ost_last_id != $mds_last ]]; then
5796                                 error "$ost_last_id != $mds_last"
5797                         else
5798                                 found=true
5799                                 break
5800                         fi
5801                 done
5802         done
5803         $found || error "can not match last_seq/last_id for $mdtosc"
5804         return 0
5805 }
5806 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5807
5808 test_54a() {
5809         perl -MSocket -e ';' || skip "no Socket perl module installed"
5810
5811         $SOCKETSERVER $DIR/socket ||
5812                 error "$SOCKETSERVER $DIR/socket failed: $?"
5813         $SOCKETCLIENT $DIR/socket ||
5814                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5815         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5816 }
5817 run_test 54a "unix domain socket test =========================="
5818
5819 test_54b() {
5820         f="$DIR/f54b"
5821         mknod $f c 1 3
5822         chmod 0666 $f
5823         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5824 }
5825 run_test 54b "char device works in lustre ======================"
5826
5827 find_loop_dev() {
5828         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5829         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5830         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5831
5832         for i in $(seq 3 7); do
5833                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5834                 LOOPDEV=$LOOPBASE$i
5835                 LOOPNUM=$i
5836                 break
5837         done
5838 }
5839
5840 cleanup_54c() {
5841         local rc=0
5842         loopdev="$DIR/loop54c"
5843
5844         trap 0
5845         $UMOUNT $DIR/$tdir || rc=$?
5846         losetup -d $loopdev || true
5847         losetup -d $LOOPDEV || true
5848         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5849         return $rc
5850 }
5851
5852 test_54c() {
5853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5854
5855         loopdev="$DIR/loop54c"
5856
5857         find_loop_dev
5858         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5859         trap cleanup_54c EXIT
5860         mknod $loopdev b 7 $LOOPNUM
5861         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5862         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5863         losetup $loopdev $DIR/$tfile ||
5864                 error "can't set up $loopdev for $DIR/$tfile"
5865         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5866         test_mkdir $DIR/$tdir
5867         mount -t ext2 $loopdev $DIR/$tdir ||
5868                 error "error mounting $loopdev on $DIR/$tdir"
5869         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5870                 error "dd write"
5871         df $DIR/$tdir
5872         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5873                 error "dd read"
5874         cleanup_54c
5875 }
5876 run_test 54c "block device works in lustre ====================="
5877
5878 test_54d() {
5879         f="$DIR/f54d"
5880         string="aaaaaa"
5881         mknod $f p
5882         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5883 }
5884 run_test 54d "fifo device works in lustre ======================"
5885
5886 test_54e() {
5887         f="$DIR/f54e"
5888         string="aaaaaa"
5889         cp -aL /dev/console $f
5890         echo $string > $f || error "echo $string to $f failed"
5891 }
5892 run_test 54e "console/tty device works in lustre ======================"
5893
5894 test_56a() {
5895         local numfiles=3
5896         local dir=$DIR/$tdir
5897
5898         rm -rf $dir
5899         test_mkdir -p $dir/dir
5900         for i in $(seq $numfiles); do
5901                 touch $dir/file$i
5902                 touch $dir/dir/file$i
5903         done
5904
5905         local numcomp=$($LFS getstripe --component-count $dir)
5906
5907         [[ $numcomp == 0 ]] && numcomp=1
5908
5909         # test lfs getstripe with --recursive
5910         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5911
5912         [[ $filenum -eq $((numfiles * 2)) ]] ||
5913                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5914         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5915         [[ $filenum -eq $numfiles ]] ||
5916                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5917         echo "$LFS getstripe showed obdidx or l_ost_idx"
5918
5919         # test lfs getstripe with file instead of dir
5920         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5921         [[ $filenum -eq 1 ]] ||
5922                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5923         echo "$LFS getstripe file1 passed"
5924
5925         #test lfs getstripe with --verbose
5926         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5927         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5928                 error "$LFS getstripe --verbose $dir: "\
5929                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5930         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5931                 error "$LFS getstripe $dir: showed lmm_magic"
5932
5933         #test lfs getstripe with -v prints lmm_fid
5934         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5935         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5936                 error "$LFS getstripe -v $dir: "\
5937                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5938         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5939                 error "$LFS getstripe $dir: showed lmm_fid by default"
5940         echo "$LFS getstripe --verbose passed"
5941
5942         #check for FID information
5943         local fid1=$($LFS getstripe --fid $dir/file1)
5944         local fid2=$($LFS getstripe --verbose $dir/file1 |
5945                      awk '/lmm_fid: / { print $2; exit; }')
5946         local fid3=$($LFS path2fid $dir/file1)
5947
5948         [ "$fid1" != "$fid2" ] &&
5949                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5950         [ "$fid1" != "$fid3" ] &&
5951                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5952         echo "$LFS getstripe --fid passed"
5953
5954         #test lfs getstripe with --obd
5955         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5956                 error "$LFS getstripe --obd wrong_uuid: should return error"
5957
5958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5959
5960         local ostidx=1
5961         local obduuid=$(ostuuid_from_index $ostidx)
5962         local found=$($LFS getstripe -r --obd $obduuid $dir |
5963                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5964
5965         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5966         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5967                 ((filenum--))
5968         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5969                 ((filenum--))
5970
5971         [[ $found -eq $filenum ]] ||
5972                 error "$LFS getstripe --obd: found $found expect $filenum"
5973         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5974                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5975                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5976                 error "$LFS getstripe --obd: should not show file on other obd"
5977         echo "$LFS getstripe --obd passed"
5978 }
5979 run_test 56a "check $LFS getstripe"
5980
5981 test_56b() {
5982         local dir=$DIR/$tdir
5983         local numdirs=3
5984
5985         test_mkdir $dir
5986         for i in $(seq $numdirs); do
5987                 test_mkdir $dir/dir$i
5988         done
5989
5990         # test lfs getdirstripe default mode is non-recursion, which is
5991         # different from lfs getstripe
5992         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5993
5994         [[ $dircnt -eq 1 ]] ||
5995                 error "$LFS getdirstripe: found $dircnt, not 1"
5996         dircnt=$($LFS getdirstripe --recursive $dir |
5997                 grep -c lmv_stripe_count)
5998         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5999                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6000 }
6001 run_test 56b "check $LFS getdirstripe"
6002
6003 test_56c() {
6004         remote_ost_nodsh && skip "remote OST with nodsh"
6005
6006         local ost_idx=0
6007         local ost_name=$(ostname_from_index $ost_idx)
6008         local old_status=$(ost_dev_status $ost_idx)
6009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6010
6011         [[ -z "$old_status" ]] ||
6012                 skip_env "OST $ost_name is in $old_status status"
6013
6014         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6015         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6016                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6017         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6018                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6019                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6020         fi
6021
6022         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6023                 error "$LFS df -v showing inactive devices"
6024         sleep_maxage
6025
6026         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6027
6028         [[ "$new_status" =~ "D" ]] ||
6029                 error "$ost_name status is '$new_status', missing 'D'"
6030         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6031                 [[ "$new_status" =~ "N" ]] ||
6032                         error "$ost_name status is '$new_status', missing 'N'"
6033         fi
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6035                 [[ "$new_status" =~ "f" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'f'"
6037         fi
6038
6039         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6040         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6041                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6042         [[ -z "$p" ]] && restore_lustre_params < $p || true
6043         sleep_maxage
6044
6045         new_status=$(ost_dev_status $ost_idx)
6046         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6047                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6048         # can't check 'f' as devices may actually be on flash
6049 }
6050 run_test 56c "check 'lfs df' showing device status"
6051
6052 test_56d() {
6053         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6054         local osts=$($LFS df -v $MOUNT | grep -c OST)
6055
6056         $LFS df $MOUNT
6057
6058         (( mdts == MDSCOUNT )) ||
6059                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6060         (( osts == OSTCOUNT )) ||
6061                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6062 }
6063 run_test 56d "'lfs df -v' prints only configured devices"
6064
6065 NUMFILES=3
6066 NUMDIRS=3
6067 setup_56() {
6068         local local_tdir="$1"
6069         local local_numfiles="$2"
6070         local local_numdirs="$3"
6071         local dir_params="$4"
6072         local dir_stripe_params="$5"
6073
6074         if [ ! -d "$local_tdir" ] ; then
6075                 test_mkdir -p $dir_stripe_params $local_tdir
6076                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6077                 for i in $(seq $local_numfiles) ; do
6078                         touch $local_tdir/file$i
6079                 done
6080                 for i in $(seq $local_numdirs) ; do
6081                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6082                         for j in $(seq $local_numfiles) ; do
6083                                 touch $local_tdir/dir$i/file$j
6084                         done
6085                 done
6086         fi
6087 }
6088
6089 setup_56_special() {
6090         local local_tdir=$1
6091         local local_numfiles=$2
6092         local local_numdirs=$3
6093
6094         setup_56 $local_tdir $local_numfiles $local_numdirs
6095
6096         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6097                 for i in $(seq $local_numfiles) ; do
6098                         mknod $local_tdir/loop${i}b b 7 $i
6099                         mknod $local_tdir/null${i}c c 1 3
6100                         ln -s $local_tdir/file1 $local_tdir/link${i}
6101                 done
6102                 for i in $(seq $local_numdirs) ; do
6103                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6104                         mknod $local_tdir/dir$i/null${i}c c 1 3
6105                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6106                 done
6107         fi
6108 }
6109
6110 test_56g() {
6111         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6112         local expected=$(($NUMDIRS + 2))
6113
6114         setup_56 $dir $NUMFILES $NUMDIRS
6115
6116         # test lfs find with -name
6117         for i in $(seq $NUMFILES) ; do
6118                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6119
6120                 [ $nums -eq $expected ] ||
6121                         error "lfs find -name '*$i' $dir wrong: "\
6122                               "found $nums, expected $expected"
6123         done
6124 }
6125 run_test 56g "check lfs find -name"
6126
6127 test_56h() {
6128         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6129         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132
6133         # test lfs find with ! -name
6134         for i in $(seq $NUMFILES) ; do
6135                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6136
6137                 [ $nums -eq $expected ] ||
6138                         error "lfs find ! -name '*$i' $dir wrong: "\
6139                               "found $nums, expected $expected"
6140         done
6141 }
6142 run_test 56h "check lfs find ! -name"
6143
6144 test_56i() {
6145         local dir=$DIR/$tdir
6146
6147         test_mkdir $dir
6148
6149         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6150         local out=$($cmd)
6151
6152         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6153 }
6154 run_test 56i "check 'lfs find -ost UUID' skips directories"
6155
6156 test_56j() {
6157         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6158
6159         setup_56_special $dir $NUMFILES $NUMDIRS
6160
6161         local expected=$((NUMDIRS + 1))
6162         local cmd="$LFS find -type d $dir"
6163         local nums=$($cmd | wc -l)
6164
6165         [ $nums -eq $expected ] ||
6166                 error "'$cmd' wrong: found $nums, expected $expected"
6167 }
6168 run_test 56j "check lfs find -type d"
6169
6170 test_56k() {
6171         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6172
6173         setup_56_special $dir $NUMFILES $NUMDIRS
6174
6175         local expected=$(((NUMDIRS + 1) * NUMFILES))
6176         local cmd="$LFS find -type f $dir"
6177         local nums=$($cmd | wc -l)
6178
6179         [ $nums -eq $expected ] ||
6180                 error "'$cmd' wrong: found $nums, expected $expected"
6181 }
6182 run_test 56k "check lfs find -type f"
6183
6184 test_56l() {
6185         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6186
6187         setup_56_special $dir $NUMFILES $NUMDIRS
6188
6189         local expected=$((NUMDIRS + NUMFILES))
6190         local cmd="$LFS find -type b $dir"
6191         local nums=$($cmd | wc -l)
6192
6193         [ $nums -eq $expected ] ||
6194                 error "'$cmd' wrong: found $nums, expected $expected"
6195 }
6196 run_test 56l "check lfs find -type b"
6197
6198 test_56m() {
6199         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6200
6201         setup_56_special $dir $NUMFILES $NUMDIRS
6202
6203         local expected=$((NUMDIRS + NUMFILES))
6204         local cmd="$LFS find -type c $dir"
6205         local nums=$($cmd | wc -l)
6206         [ $nums -eq $expected ] ||
6207                 error "'$cmd' wrong: found $nums, expected $expected"
6208 }
6209 run_test 56m "check lfs find -type c"
6210
6211 test_56n() {
6212         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6213         setup_56_special $dir $NUMFILES $NUMDIRS
6214
6215         local expected=$((NUMDIRS + NUMFILES))
6216         local cmd="$LFS find -type l $dir"
6217         local nums=$($cmd | wc -l)
6218
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221 }
6222 run_test 56n "check lfs find -type l"
6223
6224 test_56o() {
6225         local dir=$DIR/$tdir
6226
6227         setup_56 $dir $NUMFILES $NUMDIRS
6228         utime $dir/file1 > /dev/null || error "utime (1)"
6229         utime $dir/file2 > /dev/null || error "utime (2)"
6230         utime $dir/dir1 > /dev/null || error "utime (3)"
6231         utime $dir/dir2 > /dev/null || error "utime (4)"
6232         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6233         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6234
6235         local expected=4
6236         local nums=$($LFS find -mtime +0 $dir | wc -l)
6237
6238         [ $nums -eq $expected ] ||
6239                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6240
6241         expected=12
6242         cmd="$LFS find -mtime 0 $dir"
6243         nums=$($cmd | wc -l)
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246 }
6247 run_test 56o "check lfs find -mtime for old files"
6248
6249 test_56ob() {
6250         local dir=$DIR/$tdir
6251         local expected=1
6252         local count=0
6253
6254         # just to make sure there is something that won't be found
6255         test_mkdir $dir
6256         touch $dir/$tfile.now
6257
6258         for age in year week day hour min; do
6259                 count=$((count + 1))
6260
6261                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6262                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6263                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6264
6265                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6266                 local nums=$($cmd | wc -l)
6267                 [ $nums -eq $expected ] ||
6268                         error "'$cmd' wrong: found $nums, expected $expected"
6269
6270                 cmd="$LFS find $dir -atime $count${age:0:1}"
6271                 nums=$($cmd | wc -l)
6272                 [ $nums -eq $expected ] ||
6273                         error "'$cmd' wrong: found $nums, expected $expected"
6274         done
6275
6276         sleep 2
6277         cmd="$LFS find $dir -ctime +1s -type f"
6278         nums=$($cmd | wc -l)
6279         (( $nums == $count * 2 + 1)) ||
6280                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6281 }
6282 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6283
6284 test_newerXY_base() {
6285         local x=$1
6286         local y=$2
6287         local dir=$DIR/$tdir
6288         local ref
6289         local negref
6290
6291         if [ $y == "t" ]; then
6292                 if [ $x == "b" ]; then
6293                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6294                 else
6295                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6296                 fi
6297         else
6298                 ref=$DIR/$tfile.newer.$x$y
6299                 touch $ref || error "touch $ref failed"
6300         fi
6301
6302         echo "before = $ref"
6303         sleep 2
6304         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6305         sleep 2
6306         if [ $y == "t" ]; then
6307                 if [ $x == "b" ]; then
6308                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6309                 else
6310                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6311                 fi
6312         else
6313                 negref=$DIR/$tfile.negnewer.$x$y
6314                 touch $negref || error "touch $negref failed"
6315         fi
6316
6317         echo "after = $negref"
6318         local cmd="$LFS find $dir -newer$x$y $ref"
6319         local nums=$(eval $cmd | wc -l)
6320         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6321
6322         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6323                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6324
6325         cmd="$LFS find $dir ! -newer$x$y $negref"
6326         nums=$(eval $cmd | wc -l)
6327         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6328                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6329
6330         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6331         nums=$(eval $cmd | wc -l)
6332         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6333                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6334
6335         rm -rf $DIR/*
6336 }
6337
6338 test_56oc() {
6339         test_newerXY_base "a" "a"
6340         test_newerXY_base "a" "m"
6341         test_newerXY_base "a" "c"
6342         test_newerXY_base "m" "a"
6343         test_newerXY_base "m" "m"
6344         test_newerXY_base "m" "c"
6345         test_newerXY_base "c" "a"
6346         test_newerXY_base "c" "m"
6347         test_newerXY_base "c" "c"
6348
6349         [[ -n "$sles_version" ]] &&
6350                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6351
6352         test_newerXY_base "a" "t"
6353         test_newerXY_base "m" "t"
6354         test_newerXY_base "c" "t"
6355
6356         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6357            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6358                 ! btime_supported && echo "btime unsupported" && return 0
6359
6360         test_newerXY_base "b" "b"
6361         test_newerXY_base "b" "t"
6362 }
6363 run_test 56oc "check lfs find -newerXY work"
6364
6365 btime_supported() {
6366         local dir=$DIR/$tdir
6367         local rc
6368
6369         mkdir -p $dir
6370         touch $dir/$tfile
6371         $LFS find $dir -btime -1d -type f
6372         rc=$?
6373         rm -rf $dir
6374         return $rc
6375 }
6376
6377 test_56od() {
6378         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6379                 ! btime_supported && skip "btime unsupported on MDS"
6380
6381         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6382                 ! btime_supported && skip "btime unsupported on clients"
6383
6384         local dir=$DIR/$tdir
6385         local ref=$DIR/$tfile.ref
6386         local negref=$DIR/$tfile.negref
6387
6388         mkdir $dir || error "mkdir $dir failed"
6389         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6390         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6391         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6392         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6393         touch $ref || error "touch $ref failed"
6394         # sleep 3 seconds at least
6395         sleep 3
6396
6397         local before=$(do_facet mds1 date +%s)
6398         local skew=$(($(date +%s) - before + 1))
6399
6400         if (( skew < 0 && skew > -5 )); then
6401                 sleep $((0 - skew + 1))
6402                 skew=0
6403         fi
6404
6405         # Set the dir stripe params to limit files all on MDT0,
6406         # otherwise we need to calc the max clock skew between
6407         # the client and MDTs.
6408         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6409         sleep 2
6410         touch $negref || error "touch $negref failed"
6411
6412         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6413         local nums=$($cmd | wc -l)
6414         local expected=$(((NUMFILES + 1) * NUMDIRS))
6415
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418
6419         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6420         nums=$($cmd | wc -l)
6421         expected=$((NUMFILES + 1))
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         [ $skew -lt 0 ] && return
6426
6427         local after=$(do_facet mds1 date +%s)
6428         local age=$((after - before + 1 + skew))
6429
6430         cmd="$LFS find $dir -btime -${age}s -type f"
6431         nums=$($cmd | wc -l)
6432         expected=$(((NUMFILES + 1) * NUMDIRS))
6433
6434         echo "Clock skew between client and server: $skew, age:$age"
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=$(($NUMDIRS + 1))
6439         cmd="$LFS find $dir -btime -${age}s -type d"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443         rm -f $ref $negref || error "Failed to remove $ref $negref"
6444 }
6445 run_test 56od "check lfs find -btime with units"
6446
6447 test_56p() {
6448         [ $RUNAS_ID -eq $UID ] &&
6449                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6450
6451         local dir=$DIR/$tdir
6452
6453         setup_56 $dir $NUMFILES $NUMDIRS
6454         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6455
6456         local expected=$NUMFILES
6457         local cmd="$LFS find -uid $RUNAS_ID $dir"
6458         local nums=$($cmd | wc -l)
6459
6460         [ $nums -eq $expected ] ||
6461                 error "'$cmd' wrong: found $nums, expected $expected"
6462
6463         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6464         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6465         nums=$($cmd | wc -l)
6466         [ $nums -eq $expected ] ||
6467                 error "'$cmd' wrong: found $nums, expected $expected"
6468 }
6469 run_test 56p "check lfs find -uid and ! -uid"
6470
6471 test_56q() {
6472         [ $RUNAS_ID -eq $UID ] &&
6473                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6474
6475         local dir=$DIR/$tdir
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS
6478         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6479
6480         local expected=$NUMFILES
6481         local cmd="$LFS find -gid $RUNAS_GID $dir"
6482         local nums=$($cmd | wc -l)
6483
6484         [ $nums -eq $expected ] ||
6485                 error "'$cmd' wrong: found $nums, expected $expected"
6486
6487         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6488         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6489         nums=$($cmd | wc -l)
6490         [ $nums -eq $expected ] ||
6491                 error "'$cmd' wrong: found $nums, expected $expected"
6492 }
6493 run_test 56q "check lfs find -gid and ! -gid"
6494
6495 test_56r() {
6496         local dir=$DIR/$tdir
6497
6498         setup_56 $dir $NUMFILES $NUMDIRS
6499
6500         local expected=12
6501         local cmd="$LFS find -size 0 -type f -lazy $dir"
6502         local nums=$($cmd | wc -l)
6503
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506         cmd="$LFS find -size 0 -type f $dir"
6507         nums=$($cmd | wc -l)
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510
6511         expected=0
6512         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516         cmd="$LFS find ! -size 0 -type f $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520
6521         echo "test" > $dir/$tfile
6522         echo "test2" > $dir/$tfile.2 && sync
6523         expected=1
6524         cmd="$LFS find -size 5 -type f -lazy $dir"
6525         nums=$($cmd | wc -l)
6526         [ $nums -eq $expected ] ||
6527                 error "'$cmd' wrong: found $nums, expected $expected"
6528         cmd="$LFS find -size 5 -type f $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532
6533         expected=1
6534         cmd="$LFS find -size +5 -type f -lazy $dir"
6535         nums=$($cmd | wc -l)
6536         [ $nums -eq $expected ] ||
6537                 error "'$cmd' wrong: found $nums, expected $expected"
6538         cmd="$LFS find -size +5 -type f $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542
6543         expected=2
6544         cmd="$LFS find -size +0 -type f -lazy $dir"
6545         nums=$($cmd | wc -l)
6546         [ $nums -eq $expected ] ||
6547                 error "'$cmd' wrong: found $nums, expected $expected"
6548         cmd="$LFS find -size +0 -type f $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552
6553         expected=2
6554         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6555         nums=$($cmd | wc -l)
6556         [ $nums -eq $expected ] ||
6557                 error "'$cmd' wrong: found $nums, expected $expected"
6558         cmd="$LFS find ! -size -5 -type f $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562
6563         expected=12
6564         cmd="$LFS find -size -5 -type f -lazy $dir"
6565         nums=$($cmd | wc -l)
6566         [ $nums -eq $expected ] ||
6567                 error "'$cmd' wrong: found $nums, expected $expected"
6568         cmd="$LFS find -size -5 -type f $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572 }
6573 run_test 56r "check lfs find -size works"
6574
6575 test_56ra_sub() {
6576         local expected=$1
6577         local glimpses=$2
6578         local cmd="$3"
6579
6580         cancel_lru_locks $OSC
6581
6582         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6583         local nums=$($cmd | wc -l)
6584
6585         [ $nums -eq $expected ] ||
6586                 error "'$cmd' wrong: found $nums, expected $expected"
6587
6588         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6589
6590         if (( rpcs_before + glimpses != rpcs_after )); then
6591                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6592                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6593
6594                 if [[ $glimpses == 0 ]]; then
6595                         error "'$cmd' should not send glimpse RPCs to OST"
6596                 else
6597                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6598                 fi
6599         fi
6600 }
6601
6602 test_56ra() {
6603         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6604                 skip "MDS < 2.12.58 doesn't return LSOM data"
6605         local dir=$DIR/$tdir
6606         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6607
6608         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6609
6610         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6611         $LCTL set_param -n llite.*.statahead_agl=0
6612         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6613
6614         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6615         # open and close all files to ensure LSOM is updated
6616         cancel_lru_locks $OSC
6617         find $dir -type f | xargs cat > /dev/null
6618
6619         #   expect_found  glimpse_rpcs  command_to_run
6620         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6621         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6622         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6623         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6624
6625         echo "test" > $dir/$tfile
6626         echo "test2" > $dir/$tfile.2 && sync
6627         cancel_lru_locks $OSC
6628         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6629
6630         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6631         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6632         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6633         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6634
6635         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6636         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6637         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6638         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6639         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6640         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6641 }
6642 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6643
6644 test_56rb() {
6645         local dir=$DIR/$tdir
6646         local tmp=$TMP/$tfile.log
6647         local mdt_idx;
6648
6649         test_mkdir -p $dir || error "failed to mkdir $dir"
6650         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6651                 error "failed to setstripe $dir/$tfile"
6652         mdt_idx=$($LFS getdirstripe -i $dir)
6653         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6654
6655         stack_trap "rm -f $tmp" EXIT
6656         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6657         ! grep -q obd_uuid $tmp ||
6658                 error "failed to find --size +100K --ost 0 $dir"
6659         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6660         ! grep -q obd_uuid $tmp ||
6661                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6662 }
6663 run_test 56rb "check lfs find --size --ost/--mdt works"
6664
6665 test_56s() { # LU-611 #LU-9369
6666         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6667
6668         local dir=$DIR/$tdir
6669         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6672         for i in $(seq $NUMDIRS); do
6673                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6674         done
6675
6676         local expected=$NUMDIRS
6677         local cmd="$LFS find -c $OSTCOUNT $dir"
6678         local nums=$($cmd | wc -l)
6679
6680         [ $nums -eq $expected ] || {
6681                 $LFS getstripe -R $dir
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683         }
6684
6685         expected=$((NUMDIRS + onestripe))
6686         cmd="$LFS find -stripe-count +0 -type f $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] || {
6689                 $LFS getstripe -R $dir
6690                 error "'$cmd' wrong: found $nums, expected $expected"
6691         }
6692
6693         expected=$onestripe
6694         cmd="$LFS find -stripe-count 1 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] || {
6697                 $LFS getstripe -R $dir
6698                 error "'$cmd' wrong: found $nums, expected $expected"
6699         }
6700
6701         cmd="$LFS find -stripe-count -2 -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] || {
6704                 $LFS getstripe -R $dir
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706         }
6707
6708         expected=0
6709         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6710         nums=$($cmd | wc -l)
6711         [ $nums -eq $expected ] || {
6712                 $LFS getstripe -R $dir
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714         }
6715 }
6716 run_test 56s "check lfs find -stripe-count works"
6717
6718 test_56t() { # LU-611 #LU-9369
6719         local dir=$DIR/$tdir
6720
6721         setup_56 $dir 0 $NUMDIRS
6722         for i in $(seq $NUMDIRS); do
6723                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6724         done
6725
6726         local expected=$NUMDIRS
6727         local cmd="$LFS find -S 8M $dir"
6728         local nums=$($cmd | wc -l)
6729
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734         rm -rf $dir
6735
6736         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6737
6738         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6739
6740         expected=$(((NUMDIRS + 1) * NUMFILES))
6741         cmd="$LFS find -stripe-size 512k -type f $dir"
6742         nums=$($cmd | wc -l)
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745
6746         cmd="$LFS find -stripe-size +320k -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6752         cmd="$LFS find -stripe-size +200k -type f $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756
6757         cmd="$LFS find -stripe-size -640k -type f $dir"
6758         nums=$($cmd | wc -l)
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         expected=4
6763         cmd="$LFS find -stripe-size 256k -type f $dir"
6764         nums=$($cmd | wc -l)
6765         [ $nums -eq $expected ] ||
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767
6768         cmd="$LFS find -stripe-size -320k -type f $dir"
6769         nums=$($cmd | wc -l)
6770         [ $nums -eq $expected ] ||
6771                 error "'$cmd' wrong: found $nums, expected $expected"
6772
6773         expected=0
6774         cmd="$LFS find -stripe-size 1024k -type f $dir"
6775         nums=$($cmd | wc -l)
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56t "check lfs find -stripe-size works"
6780
6781 test_56u() { # LU-611
6782         local dir=$DIR/$tdir
6783
6784         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6785
6786         if [[ $OSTCOUNT -gt 1 ]]; then
6787                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6788                 onestripe=4
6789         else
6790                 onestripe=0
6791         fi
6792
6793         local expected=$(((NUMDIRS + 1) * NUMFILES))
6794         local cmd="$LFS find -stripe-index 0 -type f $dir"
6795         local nums=$($cmd | wc -l)
6796
6797         [ $nums -eq $expected ] ||
6798                 error "'$cmd' wrong: found $nums, expected $expected"
6799
6800         expected=$onestripe
6801         cmd="$LFS find -stripe-index 1 -type f $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805
6806         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6807         nums=$($cmd | wc -l)
6808         [ $nums -eq $expected ] ||
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810
6811         expected=0
6812         # This should produce an error and not return any files
6813         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6814         nums=$($cmd 2>/dev/null | wc -l)
6815         [ $nums -eq $expected ] ||
6816                 error "'$cmd' wrong: found $nums, expected $expected"
6817
6818         if [[ $OSTCOUNT -gt 1 ]]; then
6819                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6820                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6821                 nums=$($cmd | wc -l)
6822                 [ $nums -eq $expected ] ||
6823                         error "'$cmd' wrong: found $nums, expected $expected"
6824         fi
6825 }
6826 run_test 56u "check lfs find -stripe-index works"
6827
6828 test_56v() {
6829         local mdt_idx=0
6830         local dir=$DIR/$tdir
6831
6832         setup_56 $dir $NUMFILES $NUMDIRS
6833
6834         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6835         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6836
6837         for file in $($LFS find -m $UUID $dir); do
6838                 file_midx=$($LFS getstripe -m $file)
6839                 [ $file_midx -eq $mdt_idx ] ||
6840                         error "lfs find -m $UUID != getstripe -m $file_midx"
6841         done
6842 }
6843 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6844
6845 test_56w() {
6846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6848
6849         local dir=$DIR/$tdir
6850
6851         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6852
6853         local stripe_size=$($LFS getstripe -S -d $dir) ||
6854                 error "$LFS getstripe -S -d $dir failed"
6855         stripe_size=${stripe_size%% *}
6856
6857         local file_size=$((stripe_size * OSTCOUNT))
6858         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6859         local required_space=$((file_num * file_size))
6860         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6861                            head -n1)
6862         [[ $free_space -le $((required_space / 1024)) ]] &&
6863                 skip_env "need $required_space, have $free_space kbytes"
6864
6865         local dd_bs=65536
6866         local dd_count=$((file_size / dd_bs))
6867
6868         # write data into the files
6869         local i
6870         local j
6871         local file
6872
6873         for i in $(seq $NUMFILES); do
6874                 file=$dir/file$i
6875                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6876                         error "write data into $file failed"
6877         done
6878         for i in $(seq $NUMDIRS); do
6879                 for j in $(seq $NUMFILES); do
6880                         file=$dir/dir$i/file$j
6881                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6882                                 error "write data into $file failed"
6883                 done
6884         done
6885
6886         # $LFS_MIGRATE will fail if hard link migration is unsupported
6887         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6888                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6889                         error "creating links to $dir/dir1/file1 failed"
6890         fi
6891
6892         local expected=-1
6893
6894         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6895
6896         # lfs_migrate file
6897         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6898
6899         echo "$cmd"
6900         eval $cmd || error "$cmd failed"
6901
6902         check_stripe_count $dir/file1 $expected
6903
6904         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6905         then
6906                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6907                 # OST 1 if it is on OST 0. This file is small enough to
6908                 # be on only one stripe.
6909                 file=$dir/migr_1_ost
6910                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6911                         error "write data into $file failed"
6912                 local obdidx=$($LFS getstripe -i $file)
6913                 local oldmd5=$(md5sum $file)
6914                 local newobdidx=0
6915
6916                 [[ $obdidx -eq 0 ]] && newobdidx=1
6917                 cmd="$LFS migrate -i $newobdidx $file"
6918                 echo $cmd
6919                 eval $cmd || error "$cmd failed"
6920
6921                 local realobdix=$($LFS getstripe -i $file)
6922                 local newmd5=$(md5sum $file)
6923
6924                 [[ $newobdidx -ne $realobdix ]] &&
6925                         error "new OST is different (was=$obdidx, "\
6926                               "wanted=$newobdidx, got=$realobdix)"
6927                 [[ "$oldmd5" != "$newmd5" ]] &&
6928                         error "md5sum differ: $oldmd5, $newmd5"
6929         fi
6930
6931         # lfs_migrate dir
6932         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         for j in $(seq $NUMFILES); do
6937                 check_stripe_count $dir/dir1/file$j $expected
6938         done
6939
6940         # lfs_migrate works with lfs find
6941         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6942              $LFS_MIGRATE -y -c $expected"
6943         echo "$cmd"
6944         eval $cmd || error "$cmd failed"
6945
6946         for i in $(seq 2 $NUMFILES); do
6947                 check_stripe_count $dir/file$i $expected
6948         done
6949         for i in $(seq 2 $NUMDIRS); do
6950                 for j in $(seq $NUMFILES); do
6951                 check_stripe_count $dir/dir$i/file$j $expected
6952                 done
6953         done
6954 }
6955 run_test 56w "check lfs_migrate -c stripe_count works"
6956
6957 test_56wb() {
6958         local file1=$DIR/$tdir/file1
6959         local create_pool=false
6960         local initial_pool=$($LFS getstripe -p $DIR)
6961         local pool_list=()
6962         local pool=""
6963
6964         echo -n "Creating test dir..."
6965         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6966         echo "done."
6967
6968         echo -n "Creating test file..."
6969         touch $file1 || error "cannot create file"
6970         echo "done."
6971
6972         echo -n "Detecting existing pools..."
6973         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6974
6975         if [ ${#pool_list[@]} -gt 0 ]; then
6976                 echo "${pool_list[@]}"
6977                 for thispool in "${pool_list[@]}"; do
6978                         if [[ -z "$initial_pool" ||
6979                               "$initial_pool" != "$thispool" ]]; then
6980                                 pool="$thispool"
6981                                 echo "Using existing pool '$pool'"
6982                                 break
6983                         fi
6984                 done
6985         else
6986                 echo "none detected."
6987         fi
6988         if [ -z "$pool" ]; then
6989                 pool=${POOL:-testpool}
6990                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6991                 echo -n "Creating pool '$pool'..."
6992                 create_pool=true
6993                 pool_add $pool &> /dev/null ||
6994                         error "pool_add failed"
6995                 echo "done."
6996
6997                 echo -n "Adding target to pool..."
6998                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6999                         error "pool_add_targets failed"
7000                 echo "done."
7001         fi
7002
7003         echo -n "Setting pool using -p option..."
7004         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7005                 error "migrate failed rc = $?"
7006         echo "done."
7007
7008         echo -n "Verifying test file is in pool after migrating..."
7009         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7010                 error "file was not migrated to pool $pool"
7011         echo "done."
7012
7013         echo -n "Removing test file from pool '$pool'..."
7014         # "lfs migrate $file" won't remove the file from the pool
7015         # until some striping information is changed.
7016         $LFS migrate -c 1 $file1 &> /dev/null ||
7017                 error "cannot remove from pool"
7018         [ "$($LFS getstripe -p $file1)" ] &&
7019                 error "pool still set"
7020         echo "done."
7021
7022         echo -n "Setting pool using --pool option..."
7023         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7024                 error "migrate failed rc = $?"
7025         echo "done."
7026
7027         # Clean up
7028         rm -f $file1
7029         if $create_pool; then
7030                 destroy_test_pools 2> /dev/null ||
7031                         error "destroy test pools failed"
7032         fi
7033 }
7034 run_test 56wb "check lfs_migrate pool support"
7035
7036 test_56wc() {
7037         local file1="$DIR/$tdir/file1"
7038         local parent_ssize
7039         local parent_scount
7040         local cur_ssize
7041         local cur_scount
7042         local orig_ssize
7043
7044         echo -n "Creating test dir..."
7045         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7046         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7047                 error "cannot set stripe by '-S 1M -c 1'"
7048         echo "done"
7049
7050         echo -n "Setting initial stripe for test file..."
7051         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7052                 error "cannot set stripe"
7053         cur_ssize=$($LFS getstripe -S "$file1")
7054         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7055         echo "done."
7056
7057         # File currently set to -S 512K -c 1
7058
7059         # Ensure -c and -S options are rejected when -R is set
7060         echo -n "Verifying incompatible options are detected..."
7061         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7062                 error "incompatible -c and -R options not detected"
7063         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7064                 error "incompatible -S and -R options not detected"
7065         echo "done."
7066
7067         # Ensure unrecognized options are passed through to 'lfs migrate'
7068         echo -n "Verifying -S option is passed through to lfs migrate..."
7069         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7070                 error "migration failed"
7071         cur_ssize=$($LFS getstripe -S "$file1")
7072         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7073         echo "done."
7074
7075         # File currently set to -S 1M -c 1
7076
7077         # Ensure long options are supported
7078         echo -n "Verifying long options supported..."
7079         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7080                 error "long option without argument not supported"
7081         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7082                 error "long option with argument not supported"
7083         cur_ssize=$($LFS getstripe -S "$file1")
7084         [ $cur_ssize -eq 524288 ] ||
7085                 error "migrate --stripe-size $cur_ssize != 524288"
7086         echo "done."
7087
7088         # File currently set to -S 512K -c 1
7089
7090         if [ "$OSTCOUNT" -gt 1 ]; then
7091                 echo -n "Verifying explicit stripe count can be set..."
7092                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7093                         error "migrate failed"
7094                 cur_scount=$($LFS getstripe -c "$file1")
7095                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7096                 echo "done."
7097         fi
7098
7099         # File currently set to -S 512K -c 1 or -S 512K -c 2
7100
7101         # Ensure parent striping is used if -R is set, and no stripe
7102         # count or size is specified
7103         echo -n "Setting stripe for parent directory..."
7104         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7105                 error "cannot set stripe '-S 2M -c 1'"
7106         echo "done."
7107
7108         echo -n "Verifying restripe option uses parent stripe settings..."
7109         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7110         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7111         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7112                 error "migrate failed"
7113         cur_ssize=$($LFS getstripe -S "$file1")
7114         [ $cur_ssize -eq $parent_ssize ] ||
7115                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7116         cur_scount=$($LFS getstripe -c "$file1")
7117         [ $cur_scount -eq $parent_scount ] ||
7118                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7119         echo "done."
7120
7121         # File currently set to -S 1M -c 1
7122
7123         # Ensure striping is preserved if -R is not set, and no stripe
7124         # count or size is specified
7125         echo -n "Verifying striping size preserved when not specified..."
7126         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7127         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7128                 error "cannot set stripe on parent directory"
7129         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7130                 error "migrate failed"
7131         cur_ssize=$($LFS getstripe -S "$file1")
7132         [ $cur_ssize -eq $orig_ssize ] ||
7133                 error "migrate by default $cur_ssize != $orig_ssize"
7134         echo "done."
7135
7136         # Ensure file name properly detected when final option has no argument
7137         echo -n "Verifying file name properly detected..."
7138         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7139                 error "file name interpreted as option argument"
7140         echo "done."
7141
7142         # Clean up
7143         rm -f "$file1"
7144 }
7145 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7146
7147 test_56wd() {
7148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7149
7150         local file1=$DIR/$tdir/file1
7151
7152         echo -n "Creating test dir..."
7153         test_mkdir $DIR/$tdir || error "cannot create dir"
7154         echo "done."
7155
7156         echo -n "Creating test file..."
7157         touch $file1
7158         echo "done."
7159
7160         # Ensure 'lfs migrate' will fail by using a non-existent option,
7161         # and make sure rsync is not called to recover
7162         echo -n "Make sure --no-rsync option works..."
7163         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7164                 grep -q 'refusing to fall back to rsync' ||
7165                 error "rsync was called with --no-rsync set"
7166         echo "done."
7167
7168         # Ensure rsync is called without trying 'lfs migrate' first
7169         echo -n "Make sure --rsync option works..."
7170         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7171                 grep -q 'falling back to rsync' &&
7172                 error "lfs migrate was called with --rsync set"
7173         echo "done."
7174
7175         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7176         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7177                 grep -q 'at the same time' ||
7178                 error "--rsync and --no-rsync accepted concurrently"
7179         echo "done."
7180
7181         # Clean up
7182         rm -f $file1
7183 }
7184 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7185
7186 test_56we() {
7187         local td=$DIR/$tdir
7188         local tf=$td/$tfile
7189
7190         test_mkdir $td || error "cannot create $td"
7191         touch $tf || error "cannot touch $tf"
7192
7193         echo -n "Make sure --non-direct|-D works..."
7194         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7195                 grep -q "lfs migrate --non-direct" ||
7196                 error "--non-direct option cannot work correctly"
7197         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7198                 grep -q "lfs migrate -D" ||
7199                 error "-D option cannot work correctly"
7200         echo "done."
7201 }
7202 run_test 56we "check lfs_migrate --non-direct|-D support"
7203
7204 test_56x() {
7205         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7206         check_swap_layouts_support
7207
7208         local dir=$DIR/$tdir
7209         local ref1=/etc/passwd
7210         local file1=$dir/file1
7211
7212         test_mkdir $dir || error "creating dir $dir"
7213         $LFS setstripe -c 2 $file1
7214         cp $ref1 $file1
7215         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7216         stripe=$($LFS getstripe -c $file1)
7217         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7218         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7219
7220         # clean up
7221         rm -f $file1
7222 }
7223 run_test 56x "lfs migration support"
7224
7225 test_56xa() {
7226         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7227         check_swap_layouts_support
7228
7229         local dir=$DIR/$tdir/$testnum
7230
7231         test_mkdir -p $dir
7232
7233         local ref1=/etc/passwd
7234         local file1=$dir/file1
7235
7236         $LFS setstripe -c 2 $file1
7237         cp $ref1 $file1
7238         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7239
7240         local stripe=$($LFS getstripe -c $file1)
7241
7242         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7243         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7244
7245         # clean up
7246         rm -f $file1
7247 }
7248 run_test 56xa "lfs migration --block support"
7249
7250 check_migrate_links() {
7251         local dir="$1"
7252         local file1="$dir/file1"
7253         local begin="$2"
7254         local count="$3"
7255         local runas="$4"
7256         local total_count=$(($begin + $count - 1))
7257         local symlink_count=10
7258         local uniq_count=10
7259
7260         if [ ! -f "$file1" ]; then
7261                 echo -n "creating initial file..."
7262                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7263                         error "cannot setstripe initial file"
7264                 echo "done"
7265
7266                 echo -n "creating symlinks..."
7267                 for s in $(seq 1 $symlink_count); do
7268                         ln -s "$file1" "$dir/slink$s" ||
7269                                 error "cannot create symlinks"
7270                 done
7271                 echo "done"
7272
7273                 echo -n "creating nonlinked files..."
7274                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7275                         error "cannot create nonlinked files"
7276                 echo "done"
7277         fi
7278
7279         # create hard links
7280         if [ ! -f "$dir/file$total_count" ]; then
7281                 echo -n "creating hard links $begin:$total_count..."
7282                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7283                         /dev/null || error "cannot create hard links"
7284                 echo "done"
7285         fi
7286
7287         echo -n "checking number of hard links listed in xattrs..."
7288         local fid=$($LFS getstripe -F "$file1")
7289         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7290
7291         echo "${#paths[*]}"
7292         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7293                         skip "hard link list has unexpected size, skipping test"
7294         fi
7295         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7296                         error "link names should exceed xattrs size"
7297         fi
7298
7299         echo -n "migrating files..."
7300         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7301         local rc=$?
7302         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7303         echo "done"
7304
7305         # make sure all links have been properly migrated
7306         echo -n "verifying files..."
7307         fid=$($LFS getstripe -F "$file1") ||
7308                 error "cannot get fid for file $file1"
7309         for i in $(seq 2 $total_count); do
7310                 local fid2=$($LFS getstripe -F $dir/file$i)
7311
7312                 [ "$fid2" == "$fid" ] ||
7313                         error "migrated hard link has mismatched FID"
7314         done
7315
7316         # make sure hard links were properly detected, and migration was
7317         # performed only once for the entire link set; nonlinked files should
7318         # also be migrated
7319         local actual=$(grep -c 'done' <<< "$migrate_out")
7320         local expected=$(($uniq_count + 1))
7321
7322         [ "$actual" -eq  "$expected" ] ||
7323                 error "hard links individually migrated ($actual != $expected)"
7324
7325         # make sure the correct number of hard links are present
7326         local hardlinks=$(stat -c '%h' "$file1")
7327
7328         [ $hardlinks -eq $total_count ] ||
7329                 error "num hard links $hardlinks != $total_count"
7330         echo "done"
7331
7332         return 0
7333 }
7334
7335 test_56xb() {
7336         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7337                 skip "Need MDS version at least 2.10.55"
7338
7339         local dir="$DIR/$tdir"
7340
7341         test_mkdir "$dir" || error "cannot create dir $dir"
7342
7343         echo "testing lfs migrate mode when all links fit within xattrs"
7344         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7345
7346         echo "testing rsync mode when all links fit within xattrs"
7347         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7348
7349         echo "testing lfs migrate mode when all links do not fit within xattrs"
7350         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7351
7352         echo "testing rsync mode when all links do not fit within xattrs"
7353         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7354
7355         chown -R $RUNAS_ID $dir
7356         echo "testing non-root lfs migrate mode when not all links are in xattr"
7357         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7358
7359         # clean up
7360         rm -rf $dir
7361 }
7362 run_test 56xb "lfs migration hard link support"
7363
7364 test_56xc() {
7365         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7366
7367         local dir="$DIR/$tdir"
7368
7369         test_mkdir "$dir" || error "cannot create dir $dir"
7370
7371         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7372         echo -n "Setting initial stripe for 20MB test file..."
7373         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7374                 error "cannot setstripe 20MB file"
7375         echo "done"
7376         echo -n "Sizing 20MB test file..."
7377         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7378         echo "done"
7379         echo -n "Verifying small file autostripe count is 1..."
7380         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7381                 error "cannot migrate 20MB file"
7382         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7383                 error "cannot get stripe for $dir/20mb"
7384         [ $stripe_count -eq 1 ] ||
7385                 error "unexpected stripe count $stripe_count for 20MB file"
7386         rm -f "$dir/20mb"
7387         echo "done"
7388
7389         # Test 2: File is small enough to fit within the available space on
7390         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7391         # have at least an additional 1KB for each desired stripe for test 3
7392         echo -n "Setting stripe for 1GB test file..."
7393         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7394         echo "done"
7395         echo -n "Sizing 1GB test file..."
7396         # File size is 1GB + 3KB
7397         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7398         echo "done"
7399
7400         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7401         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7402         if (( avail > 524288 * OSTCOUNT )); then
7403                 echo -n "Migrating 1GB file..."
7404                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7405                         error "cannot migrate 1GB file"
7406                 echo "done"
7407                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7408                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7409                         error "cannot getstripe for 1GB file"
7410                 [ $stripe_count -eq 2 ] ||
7411                         error "unexpected stripe count $stripe_count != 2"
7412                 echo "done"
7413         fi
7414
7415         # Test 3: File is too large to fit within the available space on
7416         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7417         if [ $OSTCOUNT -ge 3 ]; then
7418                 # The required available space is calculated as
7419                 # file size (1GB + 3KB) / OST count (3).
7420                 local kb_per_ost=349526
7421
7422                 echo -n "Migrating 1GB file with limit..."
7423                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7424                         error "cannot migrate 1GB file with limit"
7425                 echo "done"
7426
7427                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7428                 echo -n "Verifying 1GB autostripe count with limited space..."
7429                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7430                         error "unexpected stripe count $stripe_count (min 3)"
7431                 echo "done"
7432         fi
7433
7434         # clean up
7435         rm -rf $dir
7436 }
7437 run_test 56xc "lfs migration autostripe"
7438
7439 test_56xd() {
7440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7441
7442         local dir=$DIR/$tdir
7443         local f_mgrt=$dir/$tfile.mgrt
7444         local f_yaml=$dir/$tfile.yaml
7445         local f_copy=$dir/$tfile.copy
7446         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7447         local layout_copy="-c 2 -S 2M -i 1"
7448         local yamlfile=$dir/yamlfile
7449         local layout_before;
7450         local layout_after;
7451
7452         test_mkdir "$dir" || error "cannot create dir $dir"
7453         $LFS setstripe $layout_yaml $f_yaml ||
7454                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7455         $LFS getstripe --yaml $f_yaml > $yamlfile
7456         $LFS setstripe $layout_copy $f_copy ||
7457                 error "cannot setstripe $f_copy with layout $layout_copy"
7458         touch $f_mgrt
7459         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7460
7461         # 1. test option --yaml
7462         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7463                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7464         layout_before=$(get_layout_param $f_yaml)
7465         layout_after=$(get_layout_param $f_mgrt)
7466         [ "$layout_after" == "$layout_before" ] ||
7467                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7468
7469         # 2. test option --copy
7470         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7471                 error "cannot migrate $f_mgrt with --copy $f_copy"
7472         layout_before=$(get_layout_param $f_copy)
7473         layout_after=$(get_layout_param $f_mgrt)
7474         [ "$layout_after" == "$layout_before" ] ||
7475                 error "lfs_migrate --copy: $layout_after != $layout_before"
7476 }
7477 run_test 56xd "check lfs_migrate --yaml and --copy support"
7478
7479 test_56xe() {
7480         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7481
7482         local dir=$DIR/$tdir
7483         local f_comp=$dir/$tfile
7484         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7485         local layout_before=""
7486         local layout_after=""
7487
7488         test_mkdir "$dir" || error "cannot create dir $dir"
7489         $LFS setstripe $layout $f_comp ||
7490                 error "cannot setstripe $f_comp with layout $layout"
7491         layout_before=$(get_layout_param $f_comp)
7492         dd if=/dev/zero of=$f_comp bs=1M count=4
7493
7494         # 1. migrate a comp layout file by lfs_migrate
7495         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7496         layout_after=$(get_layout_param $f_comp)
7497         [ "$layout_before" == "$layout_after" ] ||
7498                 error "lfs_migrate: $layout_before != $layout_after"
7499
7500         # 2. migrate a comp layout file by lfs migrate
7501         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7502         layout_after=$(get_layout_param $f_comp)
7503         [ "$layout_before" == "$layout_after" ] ||
7504                 error "lfs migrate: $layout_before != $layout_after"
7505 }
7506 run_test 56xe "migrate a composite layout file"
7507
7508 test_56xf() {
7509         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7510
7511         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7512                 skip "Need server version at least 2.13.53"
7513
7514         local dir=$DIR/$tdir
7515         local f_comp=$dir/$tfile
7516         local layout="-E 1M -c1 -E -1 -c2"
7517         local fid_before=""
7518         local fid_after=""
7519
7520         test_mkdir "$dir" || error "cannot create dir $dir"
7521         $LFS setstripe $layout $f_comp ||
7522                 error "cannot setstripe $f_comp with layout $layout"
7523         fid_before=$($LFS getstripe --fid $f_comp)
7524         dd if=/dev/zero of=$f_comp bs=1M count=4
7525
7526         # 1. migrate a comp layout file to a comp layout
7527         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7528         fid_after=$($LFS getstripe --fid $f_comp)
7529         [ "$fid_before" == "$fid_after" ] ||
7530                 error "comp-to-comp migrate: $fid_before != $fid_after"
7531
7532         # 2. migrate a comp layout file to a plain layout
7533         $LFS migrate -c2 $f_comp ||
7534                 error "cannot migrate $f_comp by lfs migrate"
7535         fid_after=$($LFS getstripe --fid $f_comp)
7536         [ "$fid_before" == "$fid_after" ] ||
7537                 error "comp-to-plain migrate: $fid_before != $fid_after"
7538
7539         # 3. migrate a plain layout file to a comp layout
7540         $LFS migrate $layout $f_comp ||
7541                 error "cannot migrate $f_comp by lfs migrate"
7542         fid_after=$($LFS getstripe --fid $f_comp)
7543         [ "$fid_before" == "$fid_after" ] ||
7544                 error "plain-to-comp migrate: $fid_before != $fid_after"
7545 }
7546 run_test 56xf "FID is not lost during migration of a composite layout file"
7547
7548 test_56y() {
7549         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7550                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7551
7552         local res=""
7553         local dir=$DIR/$tdir
7554         local f1=$dir/file1
7555         local f2=$dir/file2
7556
7557         test_mkdir -p $dir || error "creating dir $dir"
7558         touch $f1 || error "creating std file $f1"
7559         $MULTIOP $f2 H2c || error "creating released file $f2"
7560
7561         # a directory can be raid0, so ask only for files
7562         res=$($LFS find $dir -L raid0 -type f | wc -l)
7563         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7564
7565         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7566         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7567
7568         # only files can be released, so no need to force file search
7569         res=$($LFS find $dir -L released)
7570         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7571
7572         res=$($LFS find $dir -type f \! -L released)
7573         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7574 }
7575 run_test 56y "lfs find -L raid0|released"
7576
7577 test_56z() { # LU-4824
7578         # This checks to make sure 'lfs find' continues after errors
7579         # There are two classes of errors that should be caught:
7580         # - If multiple paths are provided, all should be searched even if one
7581         #   errors out
7582         # - If errors are encountered during the search, it should not terminate
7583         #   early
7584         local dir=$DIR/$tdir
7585         local i
7586
7587         test_mkdir $dir
7588         for i in d{0..9}; do
7589                 test_mkdir $dir/$i
7590                 touch $dir/$i/$tfile
7591         done
7592         $LFS find $DIR/non_existent_dir $dir &&
7593                 error "$LFS find did not return an error"
7594         # Make a directory unsearchable. This should NOT be the last entry in
7595         # directory order.  Arbitrarily pick the 6th entry
7596         chmod 700 $($LFS find $dir -type d | sed '6!d')
7597
7598         $RUNAS $LFS find $DIR/non_existent $dir
7599         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7600
7601         # The user should be able to see 10 directories and 9 files
7602         (( count == 19 )) ||
7603                 error "$LFS find found $count != 19 entries after error"
7604 }
7605 run_test 56z "lfs find should continue after an error"
7606
7607 test_56aa() { # LU-5937
7608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7609
7610         local dir=$DIR/$tdir
7611
7612         mkdir $dir
7613         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7614
7615         createmany -o $dir/striped_dir/${tfile}- 1024
7616         local dirs=$($LFS find --size +8k $dir/)
7617
7618         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7619 }
7620 run_test 56aa "lfs find --size under striped dir"
7621
7622 test_56ab() { # LU-10705
7623         test_mkdir $DIR/$tdir
7624         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7625         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7626         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7627         # Flush writes to ensure valid blocks.  Need to be more thorough for
7628         # ZFS, since blocks are not allocated/returned to client immediately.
7629         sync_all_data
7630         wait_zfs_commit ost1 2
7631         cancel_lru_locks osc
7632         ls -ls $DIR/$tdir
7633
7634         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7635
7636         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7637
7638         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7639         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7640
7641         rm -f $DIR/$tdir/$tfile.[123]
7642 }
7643 run_test 56ab "lfs find --blocks"
7644
7645 test_56ba() {
7646         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7647                 skip "Need MDS version at least 2.10.50"
7648
7649         # Create composite files with one component
7650         local dir=$DIR/$tdir
7651
7652         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7653         # Create composite files with three components
7654         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7655         # Create non-composite files
7656         createmany -o $dir/${tfile}- 10
7657
7658         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7659
7660         [[ $nfiles == 10 ]] ||
7661                 error "lfs find -E 1M found $nfiles != 10 files"
7662
7663         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7664         [[ $nfiles == 25 ]] ||
7665                 error "lfs find ! -E 1M found $nfiles != 25 files"
7666
7667         # All files have a component that starts at 0
7668         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7669         [[ $nfiles == 35 ]] ||
7670                 error "lfs find --component-start 0 - $nfiles != 35 files"
7671
7672         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7673         [[ $nfiles == 15 ]] ||
7674                 error "lfs find --component-start 2M - $nfiles != 15 files"
7675
7676         # All files created here have a componenet that does not starts at 2M
7677         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7678         [[ $nfiles == 35 ]] ||
7679                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7680
7681         # Find files with a specified number of components
7682         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7683         [[ $nfiles == 15 ]] ||
7684                 error "lfs find --component-count 3 - $nfiles != 15 files"
7685
7686         # Remember non-composite files have a component count of zero
7687         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7688         [[ $nfiles == 10 ]] ||
7689                 error "lfs find --component-count 0 - $nfiles != 10 files"
7690
7691         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7692         [[ $nfiles == 20 ]] ||
7693                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7694
7695         # All files have a flag called "init"
7696         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7697         [[ $nfiles == 35 ]] ||
7698                 error "lfs find --component-flags init - $nfiles != 35 files"
7699
7700         # Multi-component files will have a component not initialized
7701         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7702         [[ $nfiles == 15 ]] ||
7703                 error "lfs find !--component-flags init - $nfiles != 15 files"
7704
7705         rm -rf $dir
7706
7707 }
7708 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7709
7710 test_56ca() {
7711         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7712                 skip "Need MDS version at least 2.10.57"
7713
7714         local td=$DIR/$tdir
7715         local tf=$td/$tfile
7716         local dir
7717         local nfiles
7718         local cmd
7719         local i
7720         local j
7721
7722         # create mirrored directories and mirrored files
7723         mkdir $td || error "mkdir $td failed"
7724         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7725         createmany -o $tf- 10 || error "create $tf- failed"
7726
7727         for i in $(seq 2); do
7728                 dir=$td/dir$i
7729                 mkdir $dir || error "mkdir $dir failed"
7730                 $LFS mirror create -N$((3 + i)) $dir ||
7731                         error "create mirrored dir $dir failed"
7732                 createmany -o $dir/$tfile- 10 ||
7733                         error "create $dir/$tfile- failed"
7734         done
7735
7736         # change the states of some mirrored files
7737         echo foo > $tf-6
7738         for i in $(seq 2); do
7739                 dir=$td/dir$i
7740                 for j in $(seq 4 9); do
7741                         echo foo > $dir/$tfile-$j
7742                 done
7743         done
7744
7745         # find mirrored files with specific mirror count
7746         cmd="$LFS find --mirror-count 3 --type f $td"
7747         nfiles=$($cmd | wc -l)
7748         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7749
7750         cmd="$LFS find ! --mirror-count 3 --type f $td"
7751         nfiles=$($cmd | wc -l)
7752         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7753
7754         cmd="$LFS find --mirror-count +2 --type f $td"
7755         nfiles=$($cmd | wc -l)
7756         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7757
7758         cmd="$LFS find --mirror-count -6 --type f $td"
7759         nfiles=$($cmd | wc -l)
7760         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7761
7762         # find mirrored files with specific file state
7763         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7764         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7765
7766         cmd="$LFS find --mirror-state=ro --type f $td"
7767         nfiles=$($cmd | wc -l)
7768         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7769
7770         cmd="$LFS find ! --mirror-state=ro --type f $td"
7771         nfiles=$($cmd | wc -l)
7772         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7773
7774         cmd="$LFS find --mirror-state=wp --type f $td"
7775         nfiles=$($cmd | wc -l)
7776         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7777
7778         cmd="$LFS find ! --mirror-state=sp --type f $td"
7779         nfiles=$($cmd | wc -l)
7780         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7781 }
7782 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7783
7784 test_56da() { # LU-14179
7785         local path=$DIR/$tdir
7786
7787         test_mkdir $path
7788         cd $path
7789
7790         local longdir=$(str_repeat 'a' 255)
7791
7792         for i in {1..15}; do
7793                 path=$path/$longdir
7794                 test_mkdir $longdir
7795                 cd $longdir
7796         done
7797
7798         local len=${#path}
7799         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7800
7801         test_mkdir $lastdir
7802         cd $lastdir
7803         # PATH_MAX-1
7804         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7805
7806         # NAME_MAX
7807         touch $(str_repeat 'f' 255)
7808
7809         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7810                 error "lfs find reported an error"
7811
7812         rm -rf $DIR/$tdir
7813 }
7814 run_test 56da "test lfs find with long paths"
7815
7816 test_57a() {
7817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7818         # note test will not do anything if MDS is not local
7819         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7820                 skip_env "ldiskfs only test"
7821         fi
7822         remote_mds_nodsh && skip "remote MDS with nodsh"
7823
7824         local MNTDEV="osd*.*MDT*.mntdev"
7825         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7826         [ -z "$DEV" ] && error "can't access $MNTDEV"
7827         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7828                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7829                         error "can't access $DEV"
7830                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7831                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7832                 rm $TMP/t57a.dump
7833         done
7834 }
7835 run_test 57a "verify MDS filesystem created with large inodes =="
7836
7837 test_57b() {
7838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7839         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7840                 skip_env "ldiskfs only test"
7841         fi
7842         remote_mds_nodsh && skip "remote MDS with nodsh"
7843
7844         local dir=$DIR/$tdir
7845         local filecount=100
7846         local file1=$dir/f1
7847         local fileN=$dir/f$filecount
7848
7849         rm -rf $dir || error "removing $dir"
7850         test_mkdir -c1 $dir
7851         local mdtidx=$($LFS getstripe -m $dir)
7852         local mdtname=MDT$(printf %04x $mdtidx)
7853         local facet=mds$((mdtidx + 1))
7854
7855         echo "mcreating $filecount files"
7856         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7857
7858         # verify that files do not have EAs yet
7859         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7860                 error "$file1 has an EA"
7861         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7862                 error "$fileN has an EA"
7863
7864         sync
7865         sleep 1
7866         df $dir  #make sure we get new statfs data
7867         local mdsfree=$(do_facet $facet \
7868                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7869         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7870         local file
7871
7872         echo "opening files to create objects/EAs"
7873         for file in $(seq -f $dir/f%g 1 $filecount); do
7874                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7875                         error "opening $file"
7876         done
7877
7878         # verify that files have EAs now
7879         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7880         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7881
7882         sleep 1  #make sure we get new statfs data
7883         df $dir
7884         local mdsfree2=$(do_facet $facet \
7885                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7886         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7887
7888         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7889                 if [ "$mdsfree" != "$mdsfree2" ]; then
7890                         error "MDC before $mdcfree != after $mdcfree2"
7891                 else
7892                         echo "MDC before $mdcfree != after $mdcfree2"
7893                         echo "unable to confirm if MDS has large inodes"
7894                 fi
7895         fi
7896         rm -rf $dir
7897 }
7898 run_test 57b "default LOV EAs are stored inside large inodes ==="
7899
7900 test_58() {
7901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7902         [ -z "$(which wiretest 2>/dev/null)" ] &&
7903                         skip_env "could not find wiretest"
7904
7905         wiretest
7906 }
7907 run_test 58 "verify cross-platform wire constants =============="
7908
7909 test_59() {
7910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7911
7912         echo "touch 130 files"
7913         createmany -o $DIR/f59- 130
7914         echo "rm 130 files"
7915         unlinkmany $DIR/f59- 130
7916         sync
7917         # wait for commitment of removal
7918         wait_delete_completed
7919 }
7920 run_test 59 "verify cancellation of llog records async ========="
7921
7922 TEST60_HEAD="test_60 run $RANDOM"
7923 test_60a() {
7924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7925         remote_mgs_nodsh && skip "remote MGS with nodsh"
7926         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7927                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7928                         skip_env "missing subtest run-llog.sh"
7929
7930         log "$TEST60_HEAD - from kernel mode"
7931         do_facet mgs "$LCTL dk > /dev/null"
7932         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7933         do_facet mgs $LCTL dk > $TMP/$tfile
7934
7935         # LU-6388: test llog_reader
7936         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7937         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7938         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7939                         skip_env "missing llog_reader"
7940         local fstype=$(facet_fstype mgs)
7941         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7942                 skip_env "Only for ldiskfs or zfs type mgs"
7943
7944         local mntpt=$(facet_mntpt mgs)
7945         local mgsdev=$(mgsdevname 1)
7946         local fid_list
7947         local fid
7948         local rec_list
7949         local rec
7950         local rec_type
7951         local obj_file
7952         local path
7953         local seq
7954         local oid
7955         local pass=true
7956
7957         #get fid and record list
7958         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7959                 tail -n 4))
7960         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7961                 tail -n 4))
7962         #remount mgs as ldiskfs or zfs type
7963         stop mgs || error "stop mgs failed"
7964         mount_fstype mgs || error "remount mgs failed"
7965         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7966                 fid=${fid_list[i]}
7967                 rec=${rec_list[i]}
7968                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7969                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7970                 oid=$((16#$oid))
7971
7972                 case $fstype in
7973                         ldiskfs )
7974                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7975                         zfs )
7976                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7977                 esac
7978                 echo "obj_file is $obj_file"
7979                 do_facet mgs $llog_reader $obj_file
7980
7981                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7982                         awk '{ print $3 }' | sed -e "s/^type=//g")
7983                 if [ $rec_type != $rec ]; then
7984                         echo "FAILED test_60a wrong record type $rec_type," \
7985                               "should be $rec"
7986                         pass=false
7987                         break
7988                 fi
7989
7990                 #check obj path if record type is LLOG_LOGID_MAGIC
7991                 if [ "$rec" == "1064553b" ]; then
7992                         path=$(do_facet mgs $llog_reader $obj_file |
7993                                 grep "path=" | awk '{ print $NF }' |
7994                                 sed -e "s/^path=//g")
7995                         if [ $obj_file != $mntpt/$path ]; then
7996                                 echo "FAILED test_60a wrong obj path" \
7997                                       "$montpt/$path, should be $obj_file"
7998                                 pass=false
7999                                 break
8000                         fi
8001                 fi
8002         done
8003         rm -f $TMP/$tfile
8004         #restart mgs before "error", otherwise it will block the next test
8005         stop mgs || error "stop mgs failed"
8006         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8007         $pass || error "test failed, see FAILED test_60a messages for specifics"
8008 }
8009 run_test 60a "llog_test run from kernel module and test llog_reader"
8010
8011 test_60b() { # bug 6411
8012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8013
8014         dmesg > $DIR/$tfile
8015         LLOG_COUNT=$(do_facet mgs dmesg |
8016                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8017                           /llog_[a-z]*.c:[0-9]/ {
8018                                 if (marker)
8019                                         from_marker++
8020                                 from_begin++
8021                           }
8022                           END {
8023                                 if (marker)
8024                                         print from_marker
8025                                 else
8026                                         print from_begin
8027                           }")
8028
8029         [[ $LLOG_COUNT -gt 120 ]] &&
8030                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8031 }
8032 run_test 60b "limit repeated messages from CERROR/CWARN"
8033
8034 test_60c() {
8035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8036
8037         echo "create 5000 files"
8038         createmany -o $DIR/f60c- 5000
8039 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8040         lctl set_param fail_loc=0x80000137
8041         unlinkmany $DIR/f60c- 5000
8042         lctl set_param fail_loc=0
8043 }
8044 run_test 60c "unlink file when mds full"
8045
8046 test_60d() {
8047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8048
8049         SAVEPRINTK=$(lctl get_param -n printk)
8050         # verify "lctl mark" is even working"
8051         MESSAGE="test message ID $RANDOM $$"
8052         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8053         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8054
8055         lctl set_param printk=0 || error "set lnet.printk failed"
8056         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8057         MESSAGE="new test message ID $RANDOM $$"
8058         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8059         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8060         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8061
8062         lctl set_param -n printk="$SAVEPRINTK"
8063 }
8064 run_test 60d "test printk console message masking"
8065
8066 test_60e() {
8067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8068         remote_mds_nodsh && skip "remote MDS with nodsh"
8069
8070         touch $DIR/$tfile
8071 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8072         do_facet mds1 lctl set_param fail_loc=0x15b
8073         rm $DIR/$tfile
8074 }
8075 run_test 60e "no space while new llog is being created"
8076
8077 test_60f() {
8078         local old_path=$($LCTL get_param -n debug_path)
8079
8080         stack_trap "$LCTL set_param debug_path=$old_path"
8081         stack_trap "rm -f $TMP/$tfile*"
8082         rm -f $TMP/$tfile* 2> /dev/null
8083         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8084         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8085         test_mkdir $DIR/$tdir
8086         # retry in case the open is cached and not released
8087         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8088                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8089                 sleep 0.1
8090         done
8091         ls $TMP/$tfile*
8092         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8093 }
8094 run_test 60f "change debug_path works"
8095
8096 test_60g() {
8097         local pid
8098         local i
8099
8100         test_mkdir -c $MDSCOUNT $DIR/$tdir
8101
8102         (
8103                 local index=0
8104                 while true; do
8105                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8106                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8107                                 2>/dev/null
8108                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8109                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8110                         index=$((index + 1))
8111                 done
8112         ) &
8113
8114         pid=$!
8115
8116         for i in {0..100}; do
8117                 # define OBD_FAIL_OSD_TXN_START    0x19a
8118                 local index=$((i % MDSCOUNT + 1))
8119
8120                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8121                         > /dev/null
8122                 sleep 0.01
8123         done
8124
8125         kill -9 $pid
8126
8127         for i in $(seq $MDSCOUNT); do
8128                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8129         done
8130
8131         mkdir $DIR/$tdir/new || error "mkdir failed"
8132         rmdir $DIR/$tdir/new || error "rmdir failed"
8133
8134         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8135                 -t namespace
8136         for i in $(seq $MDSCOUNT); do
8137                 wait_update_facet mds$i "$LCTL get_param -n \
8138                         mdd.$(facet_svc mds$i).lfsck_namespace |
8139                         awk '/^status/ { print \\\$2 }'" "completed"
8140         done
8141
8142         ls -R $DIR/$tdir || error "ls failed"
8143         rm -rf $DIR/$tdir || error "rmdir failed"
8144 }
8145 run_test 60g "transaction abort won't cause MDT hung"
8146
8147 test_60h() {
8148         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8149                 skip "Need MDS version at least 2.12.52"
8150         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8151
8152         local f
8153
8154         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8155         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8156         for fail_loc in 0x80000188 0x80000189; do
8157                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8158                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8159                         error "mkdir $dir-$fail_loc failed"
8160                 for i in {0..10}; do
8161                         # create may fail on missing stripe
8162                         echo $i > $DIR/$tdir-$fail_loc/$i
8163                 done
8164                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8165                         error "getdirstripe $tdir-$fail_loc failed"
8166                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8167                         error "migrate $tdir-$fail_loc failed"
8168                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8169                         error "getdirstripe $tdir-$fail_loc failed"
8170                 pushd $DIR/$tdir-$fail_loc
8171                 for f in *; do
8172                         echo $f | cmp $f - || error "$f data mismatch"
8173                 done
8174                 popd
8175                 rm -rf $DIR/$tdir-$fail_loc
8176         done
8177 }
8178 run_test 60h "striped directory with missing stripes can be accessed"
8179
8180 test_61a() {
8181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8182
8183         f="$DIR/f61"
8184         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8185         cancel_lru_locks osc
8186         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8187         sync
8188 }
8189 run_test 61a "mmap() writes don't make sync hang ================"
8190
8191 test_61b() {
8192         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8193 }
8194 run_test 61b "mmap() of unstriped file is successful"
8195
8196 # bug 2330 - insufficient obd_match error checking causes LBUG
8197 test_62() {
8198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8199
8200         f="$DIR/f62"
8201         echo foo > $f
8202         cancel_lru_locks osc
8203         lctl set_param fail_loc=0x405
8204         cat $f && error "cat succeeded, expect -EIO"
8205         lctl set_param fail_loc=0
8206 }
8207 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8208 # match every page all of the time.
8209 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8210
8211 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8212 # Though this test is irrelevant anymore, it helped to reveal some
8213 # other grant bugs (LU-4482), let's keep it.
8214 test_63a() {   # was test_63
8215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8216
8217         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8218
8219         for i in `seq 10` ; do
8220                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8221                 sleep 5
8222                 kill $!
8223                 sleep 1
8224         done
8225
8226         rm -f $DIR/f63 || true
8227 }
8228 run_test 63a "Verify oig_wait interruption does not crash ======="
8229
8230 # bug 2248 - async write errors didn't return to application on sync
8231 # bug 3677 - async write errors left page locked
8232 test_63b() {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         debugsave
8236         lctl set_param debug=-1
8237
8238         # ensure we have a grant to do async writes
8239         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8240         rm $DIR/$tfile
8241
8242         sync    # sync lest earlier test intercept the fail_loc
8243
8244         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8245         lctl set_param fail_loc=0x80000406
8246         $MULTIOP $DIR/$tfile Owy && \
8247                 error "sync didn't return ENOMEM"
8248         sync; sleep 2; sync     # do a real sync this time to flush page
8249         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8250                 error "locked page left in cache after async error" || true
8251         debugrestore
8252 }
8253 run_test 63b "async write errors should be returned to fsync ==="
8254
8255 test_64a () {
8256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8257
8258         lfs df $DIR
8259         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8260 }
8261 run_test 64a "verify filter grant calculations (in kernel) ====="
8262
8263 test_64b () {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265
8266         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8267 }
8268 run_test 64b "check out-of-space detection on client"
8269
8270 test_64c() {
8271         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8272 }
8273 run_test 64c "verify grant shrink"
8274
8275 import_param() {
8276         local tgt=$1
8277         local param=$2
8278
8279         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8280 }
8281
8282 # this does exactly what osc_request.c:osc_announce_cached() does in
8283 # order to calculate max amount of grants to ask from server
8284 want_grant() {
8285         local tgt=$1
8286
8287         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8288         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8289
8290         ((rpc_in_flight++));
8291         nrpages=$((nrpages * rpc_in_flight))
8292
8293         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8294
8295         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8296
8297         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8298         local undirty=$((nrpages * PAGE_SIZE))
8299
8300         local max_extent_pages
8301         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8302         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8303         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8304         local grant_extent_tax
8305         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8306
8307         undirty=$((undirty + nrextents * grant_extent_tax))
8308
8309         echo $undirty
8310 }
8311
8312 # this is size of unit for grant allocation. It should be equal to
8313 # what tgt_grant.c:tgt_grant_chunk() calculates
8314 grant_chunk() {
8315         local tgt=$1
8316         local max_brw_size
8317         local grant_extent_tax
8318
8319         max_brw_size=$(import_param $tgt max_brw_size)
8320
8321         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8322
8323         echo $(((max_brw_size + grant_extent_tax) * 2))
8324 }
8325
8326 test_64d() {
8327         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8328                 skip "OST < 2.10.55 doesn't limit grants enough"
8329
8330         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8331
8332         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8333                 skip "no grant_param connect flag"
8334
8335         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8336
8337         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8338         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8339
8340
8341         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8342         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8343
8344         $LFS setstripe $DIR/$tfile -i 0 -c 1
8345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8346         ddpid=$!
8347
8348         while kill -0 $ddpid; do
8349                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8350
8351                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8352                         kill $ddpid
8353                         error "cur_grant $cur_grant > $max_cur_granted"
8354                 fi
8355
8356                 sleep 1
8357         done
8358 }
8359 run_test 64d "check grant limit exceed"
8360
8361 check_grants() {
8362         local tgt=$1
8363         local expected=$2
8364         local msg=$3
8365         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8366
8367         ((cur_grants == expected)) ||
8368                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8369 }
8370
8371 round_up_p2() {
8372         echo $((($1 + $2 - 1) & ~($2 - 1)))
8373 }
8374
8375 test_64e() {
8376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8377         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8378                 skip "Need OSS version at least 2.11.56"
8379
8380         # Remount client to reset grant
8381         remount_client $MOUNT || error "failed to remount client"
8382         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8383
8384         local init_grants=$(import_param $osc_tgt initial_grant)
8385
8386         check_grants $osc_tgt $init_grants "init grants"
8387
8388         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8389         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8390         local gbs=$(import_param $osc_tgt grant_block_size)
8391
8392         # write random number of bytes from max_brw_size / 4 to max_brw_size
8393         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8394         # align for direct io
8395         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8396         # round to grant consumption unit
8397         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8398
8399         local grants=$((wb_round_up + extent_tax))
8400
8401         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8402
8403         # define OBD_FAIL_TGT_NO_GRANT 0x725
8404         # make the server not grant more back
8405         do_facet ost1 $LCTL set_param fail_loc=0x725
8406         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8407
8408         do_facet ost1 $LCTL set_param fail_loc=0
8409
8410         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8411
8412         rm -f $DIR/$tfile || error "rm failed"
8413
8414         # Remount client to reset grant
8415         remount_client $MOUNT || error "failed to remount client"
8416         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8417
8418         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8419
8420         # define OBD_FAIL_TGT_NO_GRANT 0x725
8421         # make the server not grant more back
8422         do_facet ost1 $LCTL set_param fail_loc=0x725
8423         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8424         do_facet ost1 $LCTL set_param fail_loc=0
8425
8426         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8427 }
8428 run_test 64e "check grant consumption (no grant allocation)"
8429
8430 test_64f() {
8431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8432
8433         # Remount client to reset grant
8434         remount_client $MOUNT || error "failed to remount client"
8435         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8436
8437         local init_grants=$(import_param $osc_tgt initial_grant)
8438         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8439         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8440         local gbs=$(import_param $osc_tgt grant_block_size)
8441         local chunk=$(grant_chunk $osc_tgt)
8442
8443         # write random number of bytes from max_brw_size / 4 to max_brw_size
8444         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8445         # align for direct io
8446         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8447         # round to grant consumption unit
8448         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8449
8450         local grants=$((wb_round_up + extent_tax))
8451
8452         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8453         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8454                 error "error writing to $DIR/$tfile"
8455
8456         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8457                 "direct io with grant allocation"
8458
8459         rm -f $DIR/$tfile || error "rm failed"
8460
8461         # Remount client to reset grant
8462         remount_client $MOUNT || error "failed to remount client"
8463         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8464
8465         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8466
8467         local cmd="oO_WRONLY:w${write_bytes}_yc"
8468
8469         $MULTIOP $DIR/$tfile $cmd &
8470         MULTIPID=$!
8471         sleep 1
8472
8473         check_grants $osc_tgt $((init_grants - grants)) \
8474                 "buffered io, not write rpc"
8475
8476         kill -USR1 $MULTIPID
8477         wait
8478
8479         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8480                 "buffered io, one RPC"
8481 }
8482 run_test 64f "check grant consumption (with grant allocation)"
8483
8484 # bug 1414 - set/get directories' stripe info
8485 test_65a() {
8486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8487
8488         test_mkdir $DIR/$tdir
8489         touch $DIR/$tdir/f1
8490         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8491 }
8492 run_test 65a "directory with no stripe info"
8493
8494 test_65b() {
8495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8496
8497         test_mkdir $DIR/$tdir
8498         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8499
8500         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8501                                                 error "setstripe"
8502         touch $DIR/$tdir/f2
8503         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8504 }
8505 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8506
8507 test_65c() {
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8510
8511         test_mkdir $DIR/$tdir
8512         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8513
8514         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8515                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8516         touch $DIR/$tdir/f3
8517         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8518 }
8519 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8520
8521 test_65d() {
8522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8523
8524         test_mkdir $DIR/$tdir
8525         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8526         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8527
8528         if [[ $STRIPECOUNT -le 0 ]]; then
8529                 sc=1
8530         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8531                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8532                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8533         else
8534                 sc=$(($STRIPECOUNT - 1))
8535         fi
8536         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8537         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8538         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8539                 error "lverify failed"
8540 }
8541 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8542
8543 test_65e() {
8544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8545
8546         test_mkdir $DIR/$tdir
8547
8548         $LFS setstripe $DIR/$tdir || error "setstripe"
8549         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8550                                         error "no stripe info failed"
8551         touch $DIR/$tdir/f6
8552         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8553 }
8554 run_test 65e "directory setstripe defaults"
8555
8556 test_65f() {
8557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8558
8559         test_mkdir $DIR/${tdir}f
8560         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8561                 error "setstripe succeeded" || true
8562 }
8563 run_test 65f "dir setstripe permission (should return error) ==="
8564
8565 test_65g() {
8566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8567
8568         test_mkdir $DIR/$tdir
8569         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8570
8571         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8572                 error "setstripe -S failed"
8573         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8574         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8575                 error "delete default stripe failed"
8576 }
8577 run_test 65g "directory setstripe -d"
8578
8579 test_65h() {
8580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8581
8582         test_mkdir $DIR/$tdir
8583         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8584
8585         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8586                 error "setstripe -S failed"
8587         test_mkdir $DIR/$tdir/dd1
8588         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8589                 error "stripe info inherit failed"
8590 }
8591 run_test 65h "directory stripe info inherit ===================="
8592
8593 test_65i() {
8594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8595
8596         save_layout_restore_at_exit $MOUNT
8597
8598         # bug6367: set non-default striping on root directory
8599         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8600
8601         # bug12836: getstripe on -1 default directory striping
8602         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8603
8604         # bug12836: getstripe -v on -1 default directory striping
8605         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8606
8607         # bug12836: new find on -1 default directory striping
8608         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8609 }
8610 run_test 65i "various tests to set root directory striping"
8611
8612 test_65j() { # bug6367
8613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8614
8615         sync; sleep 1
8616
8617         # if we aren't already remounting for each test, do so for this test
8618         if [ "$I_MOUNTED" = "yes" ]; then
8619                 cleanup || error "failed to unmount"
8620                 setup
8621         fi
8622
8623         save_layout_restore_at_exit $MOUNT
8624
8625         $LFS setstripe -d $MOUNT || error "setstripe failed"
8626 }
8627 run_test 65j "set default striping on root directory (bug 6367)="
8628
8629 cleanup_65k() {
8630         rm -rf $DIR/$tdir
8631         wait_delete_completed
8632         do_facet $SINGLEMDS "lctl set_param -n \
8633                 osp.$ost*MDT0000.max_create_count=$max_count"
8634         do_facet $SINGLEMDS "lctl set_param -n \
8635                 osp.$ost*MDT0000.create_count=$count"
8636         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8637         echo $INACTIVE_OSC "is Activate"
8638
8639         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8640 }
8641
8642 test_65k() { # bug11679
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8645         remote_mds_nodsh && skip "remote MDS with nodsh"
8646
8647         local disable_precreate=true
8648         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8649                 disable_precreate=false
8650
8651         echo "Check OST status: "
8652         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8653                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8654
8655         for OSC in $MDS_OSCS; do
8656                 echo $OSC "is active"
8657                 do_facet $SINGLEMDS lctl --device %$OSC activate
8658         done
8659
8660         for INACTIVE_OSC in $MDS_OSCS; do
8661                 local ost=$(osc_to_ost $INACTIVE_OSC)
8662                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8663                                lov.*md*.target_obd |
8664                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8665
8666                 mkdir -p $DIR/$tdir
8667                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8668                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8669
8670                 echo "Deactivate: " $INACTIVE_OSC
8671                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8672
8673                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8674                               osp.$ost*MDT0000.create_count")
8675                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8676                                   osp.$ost*MDT0000.max_create_count")
8677                 $disable_precreate &&
8678                         do_facet $SINGLEMDS "lctl set_param -n \
8679                                 osp.$ost*MDT0000.max_create_count=0"
8680
8681                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8682                         [ -f $DIR/$tdir/$idx ] && continue
8683                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8684                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8685                                 { cleanup_65k;
8686                                   error "setstripe $idx should succeed"; }
8687                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8688                 done
8689                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8690                 rmdir $DIR/$tdir
8691
8692                 do_facet $SINGLEMDS "lctl set_param -n \
8693                         osp.$ost*MDT0000.max_create_count=$max_count"
8694                 do_facet $SINGLEMDS "lctl set_param -n \
8695                         osp.$ost*MDT0000.create_count=$count"
8696                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8697                 echo $INACTIVE_OSC "is Activate"
8698
8699                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8700         done
8701 }
8702 run_test 65k "validate manual striping works properly with deactivated OSCs"
8703
8704 test_65l() { # bug 12836
8705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8706
8707         test_mkdir -p $DIR/$tdir/test_dir
8708         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8709         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8710 }
8711 run_test 65l "lfs find on -1 stripe dir ========================"
8712
8713 test_65m() {
8714         local layout=$(save_layout $MOUNT)
8715         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8716                 restore_layout $MOUNT $layout
8717                 error "setstripe should fail by non-root users"
8718         }
8719         true
8720 }
8721 run_test 65m "normal user can't set filesystem default stripe"
8722
8723 test_65n() {
8724         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8725         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8726                 skip "Need MDS version at least 2.12.50"
8727         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8728
8729         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8730         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8731         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8732
8733         local root_layout=$(save_layout $MOUNT)
8734         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8735
8736         # new subdirectory under root directory should not inherit
8737         # the default layout from root
8738         local dir1=$MOUNT/$tdir-1
8739         mkdir $dir1 || error "mkdir $dir1 failed"
8740         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8741                 error "$dir1 shouldn't have LOV EA"
8742
8743         # delete the default layout on root directory
8744         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8745
8746         local dir2=$MOUNT/$tdir-2
8747         mkdir $dir2 || error "mkdir $dir2 failed"
8748         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8749                 error "$dir2 shouldn't have LOV EA"
8750
8751         # set a new striping pattern on root directory
8752         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8753         local new_def_stripe_size=$((def_stripe_size * 2))
8754         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8755                 error "set stripe size on $MOUNT failed"
8756
8757         # new file created in $dir2 should inherit the new stripe size from
8758         # the filesystem default
8759         local file2=$dir2/$tfile-2
8760         touch $file2 || error "touch $file2 failed"
8761
8762         local file2_stripe_size=$($LFS getstripe -S $file2)
8763         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8764         {
8765                 echo "file2_stripe_size: '$file2_stripe_size'"
8766                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8767                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8768         }
8769
8770         local dir3=$MOUNT/$tdir-3
8771         mkdir $dir3 || error "mkdir $dir3 failed"
8772         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8773         # the root layout, which is the actual default layout that will be used
8774         # when new files are created in $dir3.
8775         local dir3_layout=$(get_layout_param $dir3)
8776         local root_dir_layout=$(get_layout_param $MOUNT)
8777         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8778         {
8779                 echo "dir3_layout: '$dir3_layout'"
8780                 echo "root_dir_layout: '$root_dir_layout'"
8781                 error "$dir3 should show the default layout from $MOUNT"
8782         }
8783
8784         # set OST pool on root directory
8785         local pool=$TESTNAME
8786         pool_add $pool || error "add $pool failed"
8787         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8788                 error "add targets to $pool failed"
8789
8790         $LFS setstripe -p $pool $MOUNT ||
8791                 error "set OST pool on $MOUNT failed"
8792
8793         # new file created in $dir3 should inherit the pool from
8794         # the filesystem default
8795         local file3=$dir3/$tfile-3
8796         touch $file3 || error "touch $file3 failed"
8797
8798         local file3_pool=$($LFS getstripe -p $file3)
8799         [[ "$file3_pool" = "$pool" ]] ||
8800                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8801
8802         local dir4=$MOUNT/$tdir-4
8803         mkdir $dir4 || error "mkdir $dir4 failed"
8804         local dir4_layout=$(get_layout_param $dir4)
8805         root_dir_layout=$(get_layout_param $MOUNT)
8806         echo "$LFS getstripe -d $dir4"
8807         $LFS getstripe -d $dir4
8808         echo "$LFS getstripe -d $MOUNT"
8809         $LFS getstripe -d $MOUNT
8810         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8811         {
8812                 echo "dir4_layout: '$dir4_layout'"
8813                 echo "root_dir_layout: '$root_dir_layout'"
8814                 error "$dir4 should show the default layout from $MOUNT"
8815         }
8816
8817         # new file created in $dir4 should inherit the pool from
8818         # the filesystem default
8819         local file4=$dir4/$tfile-4
8820         touch $file4 || error "touch $file4 failed"
8821
8822         local file4_pool=$($LFS getstripe -p $file4)
8823         [[ "$file4_pool" = "$pool" ]] ||
8824                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8825
8826         # new subdirectory under non-root directory should inherit
8827         # the default layout from its parent directory
8828         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8829                 error "set directory layout on $dir4 failed"
8830
8831         local dir5=$dir4/$tdir-5
8832         mkdir $dir5 || error "mkdir $dir5 failed"
8833
8834         dir4_layout=$(get_layout_param $dir4)
8835         local dir5_layout=$(get_layout_param $dir5)
8836         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8837         {
8838                 echo "dir4_layout: '$dir4_layout'"
8839                 echo "dir5_layout: '$dir5_layout'"
8840                 error "$dir5 should inherit the default layout from $dir4"
8841         }
8842
8843         # though subdir under ROOT doesn't inherit default layout, but
8844         # its sub dir/file should be created with default layout.
8845         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8846         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8847                 skip "Need MDS version at least 2.12.59"
8848
8849         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8850         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8851         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8852
8853         if [ $default_lmv_hash == "none" ]; then
8854                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8855         else
8856                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8857                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8858         fi
8859
8860         $LFS setdirstripe -D -c 2 $MOUNT ||
8861                 error "setdirstripe -D -c 2 failed"
8862         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8863         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8864         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8865 }
8866 run_test 65n "don't inherit default layout from root for new subdirectories"
8867
8868 # bug 2543 - update blocks count on client
8869 test_66() {
8870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8871
8872         COUNT=${COUNT:-8}
8873         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8874         sync; sync_all_data; sync; sync_all_data
8875         cancel_lru_locks osc
8876         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8877         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8878 }
8879 run_test 66 "update inode blocks count on client ==============="
8880
8881 meminfo() {
8882         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8883 }
8884
8885 swap_used() {
8886         swapon -s | awk '($1 == "'$1'") { print $4 }'
8887 }
8888
8889 # bug5265, obdfilter oa2dentry return -ENOENT
8890 # #define OBD_FAIL_SRV_ENOENT 0x217
8891 test_69() {
8892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8893         remote_ost_nodsh && skip "remote OST with nodsh"
8894
8895         f="$DIR/$tfile"
8896         $LFS setstripe -c 1 -i 0 $f
8897
8898         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8899
8900         do_facet ost1 lctl set_param fail_loc=0x217
8901         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8902         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8903
8904         do_facet ost1 lctl set_param fail_loc=0
8905         $DIRECTIO write $f 0 2 || error "write error"
8906
8907         cancel_lru_locks osc
8908         $DIRECTIO read $f 0 1 || error "read error"
8909
8910         do_facet ost1 lctl set_param fail_loc=0x217
8911         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8912
8913         do_facet ost1 lctl set_param fail_loc=0
8914         rm -f $f
8915 }
8916 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8917
8918 test_71() {
8919         test_mkdir $DIR/$tdir
8920         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8921         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8922 }
8923 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8924
8925 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         [ "$RUNAS_ID" = "$UID" ] &&
8928                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8929         # Check that testing environment is properly set up. Skip if not
8930         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8931                 skip_env "User $RUNAS_ID does not exist - skipping"
8932
8933         touch $DIR/$tfile
8934         chmod 777 $DIR/$tfile
8935         chmod ug+s $DIR/$tfile
8936         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8937                 error "$RUNAS dd $DIR/$tfile failed"
8938         # See if we are still setuid/sgid
8939         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8940                 error "S/gid is not dropped on write"
8941         # Now test that MDS is updated too
8942         cancel_lru_locks mdc
8943         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8944                 error "S/gid is not dropped on MDS"
8945         rm -f $DIR/$tfile
8946 }
8947 run_test 72a "Test that remove suid works properly (bug5695) ===="
8948
8949 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8950         local perm
8951
8952         [ "$RUNAS_ID" = "$UID" ] &&
8953                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8954         [ "$RUNAS_ID" -eq 0 ] &&
8955                 skip_env "RUNAS_ID = 0 -- skipping"
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957         # Check that testing environment is properly set up. Skip if not
8958         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8959                 skip_env "User $RUNAS_ID does not exist - skipping"
8960
8961         touch $DIR/${tfile}-f{g,u}
8962         test_mkdir $DIR/${tfile}-dg
8963         test_mkdir $DIR/${tfile}-du
8964         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8965         chmod g+s $DIR/${tfile}-{f,d}g
8966         chmod u+s $DIR/${tfile}-{f,d}u
8967         for perm in 777 2777 4777; do
8968                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8969                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8970                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8971                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8972         done
8973         true
8974 }
8975 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8976
8977 # bug 3462 - multiple simultaneous MDC requests
8978 test_73() {
8979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8980
8981         test_mkdir $DIR/d73-1
8982         test_mkdir $DIR/d73-2
8983         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8984         pid1=$!
8985
8986         lctl set_param fail_loc=0x80000129
8987         $MULTIOP $DIR/d73-1/f73-2 Oc &
8988         sleep 1
8989         lctl set_param fail_loc=0
8990
8991         $MULTIOP $DIR/d73-2/f73-3 Oc &
8992         pid3=$!
8993
8994         kill -USR1 $pid1
8995         wait $pid1 || return 1
8996
8997         sleep 25
8998
8999         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9000         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9001         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9002
9003         rm -rf $DIR/d73-*
9004 }
9005 run_test 73 "multiple MDC requests (should not deadlock)"
9006
9007 test_74a() { # bug 6149, 6184
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009
9010         touch $DIR/f74a
9011         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9012         #
9013         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9014         # will spin in a tight reconnection loop
9015         $LCTL set_param fail_loc=0x8000030e
9016         # get any lock that won't be difficult - lookup works.
9017         ls $DIR/f74a
9018         $LCTL set_param fail_loc=0
9019         rm -f $DIR/f74a
9020         true
9021 }
9022 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9023
9024 test_74b() { # bug 13310
9025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9026
9027         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9028         #
9029         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9030         # will spin in a tight reconnection loop
9031         $LCTL set_param fail_loc=0x8000030e
9032         # get a "difficult" lock
9033         touch $DIR/f74b
9034         $LCTL set_param fail_loc=0
9035         rm -f $DIR/f74b
9036         true
9037 }
9038 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9039
9040 test_74c() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042
9043         #define OBD_FAIL_LDLM_NEW_LOCK
9044         $LCTL set_param fail_loc=0x319
9045         touch $DIR/$tfile && error "touch successful"
9046         $LCTL set_param fail_loc=0
9047         true
9048 }
9049 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9050
9051 slab_lic=/sys/kernel/slab/lustre_inode_cache
9052 num_objects() {
9053         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9054         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9055                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9056 }
9057
9058 test_76a() { # Now for b=20433, added originally in b=1443
9059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9060
9061         cancel_lru_locks osc
9062         # there may be some slab objects cached per core
9063         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9064         local before=$(num_objects)
9065         local count=$((512 * cpus))
9066         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9067         local margin=$((count / 10))
9068         if [[ -f $slab_lic/aliases ]]; then
9069                 local aliases=$(cat $slab_lic/aliases)
9070                 (( aliases > 0 )) && margin=$((margin * aliases))
9071         fi
9072
9073         echo "before slab objects: $before"
9074         for i in $(seq $count); do
9075                 touch $DIR/$tfile
9076                 rm -f $DIR/$tfile
9077         done
9078         cancel_lru_locks osc
9079         local after=$(num_objects)
9080         echo "created: $count, after slab objects: $after"
9081         # shared slab counts are not very accurate, allow significant margin
9082         # the main goal is that the cache growth is not permanently > $count
9083         while (( after > before + margin )); do
9084                 sleep 1
9085                 after=$(num_objects)
9086                 wait=$((wait + 1))
9087                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9088                 if (( wait > 60 )); then
9089                         error "inode slab grew from $before+$margin to $after"
9090                 fi
9091         done
9092 }
9093 run_test 76a "confirm clients recycle inodes properly ===="
9094
9095 test_76b() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9098
9099         local count=512
9100         local before=$(num_objects)
9101
9102         for i in $(seq $count); do
9103                 mkdir $DIR/$tdir
9104                 rmdir $DIR/$tdir
9105         done
9106
9107         local after=$(num_objects)
9108         local wait=0
9109
9110         while (( after > before )); do
9111                 sleep 1
9112                 after=$(num_objects)
9113                 wait=$((wait + 1))
9114                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9115                 if (( wait > 60 )); then
9116                         error "inode slab grew from $before to $after"
9117                 fi
9118         done
9119
9120         echo "slab objects before: $before, after: $after"
9121 }
9122 run_test 76b "confirm clients recycle directory inodes properly ===="
9123
9124 export ORIG_CSUM=""
9125 set_checksums()
9126 {
9127         # Note: in sptlrpc modes which enable its own bulk checksum, the
9128         # original crc32_le bulk checksum will be automatically disabled,
9129         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9130         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9131         # In this case set_checksums() will not be no-op, because sptlrpc
9132         # bulk checksum will be enabled all through the test.
9133
9134         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9135         lctl set_param -n osc.*.checksums $1
9136         return 0
9137 }
9138
9139 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9140                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9141 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9142                              tr -d [] | head -n1)}
9143 set_checksum_type()
9144 {
9145         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9146         rc=$?
9147         log "set checksum type to $1, rc = $rc"
9148         return $rc
9149 }
9150
9151 get_osc_checksum_type()
9152 {
9153         # arugment 1: OST name, like OST0000
9154         ost=$1
9155         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9156                         sed 's/.*\[\(.*\)\].*/\1/g')
9157         rc=$?
9158         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9159         echo $checksum_type
9160 }
9161
9162 F77_TMP=$TMP/f77-temp
9163 F77SZ=8
9164 setup_f77() {
9165         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9166                 error "error writing to $F77_TMP"
9167 }
9168
9169 test_77a() { # bug 10889
9170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9171         $GSS && skip_env "could not run with gss"
9172
9173         [ ! -f $F77_TMP ] && setup_f77
9174         set_checksums 1
9175         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9176         set_checksums 0
9177         rm -f $DIR/$tfile
9178 }
9179 run_test 77a "normal checksum read/write operation"
9180
9181 test_77b() { # bug 10889
9182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9183         $GSS && skip_env "could not run with gss"
9184
9185         [ ! -f $F77_TMP ] && setup_f77
9186         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9187         $LCTL set_param fail_loc=0x80000409
9188         set_checksums 1
9189
9190         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9191                 error "dd error: $?"
9192         $LCTL set_param fail_loc=0
9193
9194         for algo in $CKSUM_TYPES; do
9195                 cancel_lru_locks osc
9196                 set_checksum_type $algo
9197                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9198                 $LCTL set_param fail_loc=0x80000408
9199                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9200                 $LCTL set_param fail_loc=0
9201         done
9202         set_checksums 0
9203         set_checksum_type $ORIG_CSUM_TYPE
9204         rm -f $DIR/$tfile
9205 }
9206 run_test 77b "checksum error on client write, read"
9207
9208 cleanup_77c() {
9209         trap 0
9210         set_checksums 0
9211         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9212         $check_ost &&
9213                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9214         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9215         $check_ost && [ -n "$ost_file_prefix" ] &&
9216                 do_facet ost1 rm -f ${ost_file_prefix}\*
9217 }
9218
9219 test_77c() {
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221         $GSS && skip_env "could not run with gss"
9222         remote_ost_nodsh && skip "remote OST with nodsh"
9223
9224         local bad1
9225         local osc_file_prefix
9226         local osc_file
9227         local check_ost=false
9228         local ost_file_prefix
9229         local ost_file
9230         local orig_cksum
9231         local dump_cksum
9232         local fid
9233
9234         # ensure corruption will occur on first OSS/OST
9235         $LFS setstripe -i 0 $DIR/$tfile
9236
9237         [ ! -f $F77_TMP ] && setup_f77
9238         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9239                 error "dd write error: $?"
9240         fid=$($LFS path2fid $DIR/$tfile)
9241
9242         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9243         then
9244                 check_ost=true
9245                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9246                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9247         else
9248                 echo "OSS do not support bulk pages dump upon error"
9249         fi
9250
9251         osc_file_prefix=$($LCTL get_param -n debug_path)
9252         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9253
9254         trap cleanup_77c EXIT
9255
9256         set_checksums 1
9257         # enable bulk pages dump upon error on Client
9258         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9259         # enable bulk pages dump upon error on OSS
9260         $check_ost &&
9261                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9262
9263         # flush Client cache to allow next read to reach OSS
9264         cancel_lru_locks osc
9265
9266         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9267         $LCTL set_param fail_loc=0x80000408
9268         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9269         $LCTL set_param fail_loc=0
9270
9271         rm -f $DIR/$tfile
9272
9273         # check cksum dump on Client
9274         osc_file=$(ls ${osc_file_prefix}*)
9275         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9276         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9277         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9278         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9279         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9280                      cksum)
9281         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9282         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9283                 error "dump content does not match on Client"
9284
9285         $check_ost || skip "No need to check cksum dump on OSS"
9286
9287         # check cksum dump on OSS
9288         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9289         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9290         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9291         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9292         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9293                 error "dump content does not match on OSS"
9294
9295         cleanup_77c
9296 }
9297 run_test 77c "checksum error on client read with debug"
9298
9299 test_77d() { # bug 10889
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         $GSS && skip_env "could not run with gss"
9302
9303         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9304         $LCTL set_param fail_loc=0x80000409
9305         set_checksums 1
9306         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9307                 error "direct write: rc=$?"
9308         $LCTL set_param fail_loc=0
9309         set_checksums 0
9310
9311         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9312         $LCTL set_param fail_loc=0x80000408
9313         set_checksums 1
9314         cancel_lru_locks osc
9315         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9316                 error "direct read: rc=$?"
9317         $LCTL set_param fail_loc=0
9318         set_checksums 0
9319 }
9320 run_test 77d "checksum error on OST direct write, read"
9321
9322 test_77f() { # bug 10889
9323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9324         $GSS && skip_env "could not run with gss"
9325
9326         set_checksums 1
9327         for algo in $CKSUM_TYPES; do
9328                 cancel_lru_locks osc
9329                 set_checksum_type $algo
9330                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9331                 $LCTL set_param fail_loc=0x409
9332                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9333                         error "direct write succeeded"
9334                 $LCTL set_param fail_loc=0
9335         done
9336         set_checksum_type $ORIG_CSUM_TYPE
9337         set_checksums 0
9338 }
9339 run_test 77f "repeat checksum error on write (expect error)"
9340
9341 test_77g() { # bug 10889
9342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9343         $GSS && skip_env "could not run with gss"
9344         remote_ost_nodsh && skip "remote OST with nodsh"
9345
9346         [ ! -f $F77_TMP ] && setup_f77
9347
9348         local file=$DIR/$tfile
9349         stack_trap "rm -f $file" EXIT
9350
9351         $LFS setstripe -c 1 -i 0 $file
9352         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9353         do_facet ost1 lctl set_param fail_loc=0x8000021a
9354         set_checksums 1
9355         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9356                 error "write error: rc=$?"
9357         do_facet ost1 lctl set_param fail_loc=0
9358         set_checksums 0
9359
9360         cancel_lru_locks osc
9361         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9362         do_facet ost1 lctl set_param fail_loc=0x8000021b
9363         set_checksums 1
9364         cmp $F77_TMP $file || error "file compare failed"
9365         do_facet ost1 lctl set_param fail_loc=0
9366         set_checksums 0
9367 }
9368 run_test 77g "checksum error on OST write, read"
9369
9370 test_77k() { # LU-10906
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372         $GSS && skip_env "could not run with gss"
9373
9374         local cksum_param="osc.$FSNAME*.checksums"
9375         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9376         local checksum
9377         local i
9378
9379         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9380         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9381         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9382
9383         for i in 0 1; do
9384                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9385                         error "failed to set checksum=$i on MGS"
9386                 wait_update $HOSTNAME "$get_checksum" $i
9387                 #remount
9388                 echo "remount client, checksum should be $i"
9389                 remount_client $MOUNT || error "failed to remount client"
9390                 checksum=$(eval $get_checksum)
9391                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9392         done
9393         # remove persistent param to avoid races with checksum mountopt below
9394         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9395                 error "failed to delete checksum on MGS"
9396
9397         for opt in "checksum" "nochecksum"; do
9398                 #remount with mount option
9399                 echo "remount client with option $opt, checksum should be $i"
9400                 umount_client $MOUNT || error "failed to umount client"
9401                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9402                         error "failed to mount client with option '$opt'"
9403                 checksum=$(eval $get_checksum)
9404                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9405                 i=$((i - 1))
9406         done
9407
9408         remount_client $MOUNT || error "failed to remount client"
9409 }
9410 run_test 77k "enable/disable checksum correctly"
9411
9412 test_77l() {
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9414         $GSS && skip_env "could not run with gss"
9415
9416         set_checksums 1
9417         stack_trap "set_checksums $ORIG_CSUM" EXIT
9418         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9419
9420         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9421
9422         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9423         for algo in $CKSUM_TYPES; do
9424                 set_checksum_type $algo || error "fail to set checksum type $algo"
9425                 osc_algo=$(get_osc_checksum_type OST0000)
9426                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9427
9428                 # no locks, no reqs to let the connection idle
9429                 cancel_lru_locks osc
9430                 lru_resize_disable osc
9431                 wait_osc_import_state client ost1 IDLE
9432
9433                 # ensure ost1 is connected
9434                 stat $DIR/$tfile >/dev/null || error "can't stat"
9435                 wait_osc_import_state client ost1 FULL
9436
9437                 osc_algo=$(get_osc_checksum_type OST0000)
9438                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9439         done
9440         return 0
9441 }
9442 run_test 77l "preferred checksum type is remembered after reconnected"
9443
9444 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9445 rm -f $F77_TMP
9446 unset F77_TMP
9447
9448 cleanup_test_78() {
9449         trap 0
9450         rm -f $DIR/$tfile
9451 }
9452
9453 test_78() { # bug 10901
9454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9455         remote_ost || skip_env "local OST"
9456
9457         NSEQ=5
9458         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9459         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9460         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9461         echo "MemTotal: $MEMTOTAL"
9462
9463         # reserve 256MB of memory for the kernel and other running processes,
9464         # and then take 1/2 of the remaining memory for the read/write buffers.
9465         if [ $MEMTOTAL -gt 512 ] ;then
9466                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9467         else
9468                 # for those poor memory-starved high-end clusters...
9469                 MEMTOTAL=$((MEMTOTAL / 2))
9470         fi
9471         echo "Mem to use for directio: $MEMTOTAL"
9472
9473         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9474         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9475         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9476         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9477                 head -n1)
9478         echo "Smallest OST: $SMALLESTOST"
9479         [[ $SMALLESTOST -lt 10240 ]] &&
9480                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9481
9482         trap cleanup_test_78 EXIT
9483
9484         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9485                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9486
9487         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9488         echo "File size: $F78SIZE"
9489         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9490         for i in $(seq 1 $NSEQ); do
9491                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9492                 echo directIO rdwr round $i of $NSEQ
9493                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9494         done
9495
9496         cleanup_test_78
9497 }
9498 run_test 78 "handle large O_DIRECT writes correctly ============"
9499
9500 test_79() { # bug 12743
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502
9503         wait_delete_completed
9504
9505         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9506         BKFREE=$(calc_osc_kbytes kbytesfree)
9507         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9508
9509         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9510         DFTOTAL=`echo $STRING | cut -d, -f1`
9511         DFUSED=`echo $STRING  | cut -d, -f2`
9512         DFAVAIL=`echo $STRING | cut -d, -f3`
9513         DFFREE=$(($DFTOTAL - $DFUSED))
9514
9515         ALLOWANCE=$((64 * $OSTCOUNT))
9516
9517         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9518            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9519                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9520         fi
9521         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9522            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9523                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9524         fi
9525         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9526            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9527                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9528         fi
9529 }
9530 run_test 79 "df report consistency check ======================="
9531
9532 test_80() { # bug 10718
9533         remote_ost_nodsh && skip "remote OST with nodsh"
9534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9535
9536         # relax strong synchronous semantics for slow backends like ZFS
9537         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9538                 local soc="obdfilter.*.sync_lock_cancel"
9539                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9540
9541                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9542                 if [ -z "$save" ]; then
9543                         soc="obdfilter.*.sync_on_lock_cancel"
9544                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9545                 fi
9546
9547                 if [ "$save" != "never" ]; then
9548                         local hosts=$(comma_list $(osts_nodes))
9549
9550                         do_nodes $hosts $LCTL set_param $soc=never
9551                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9552                 fi
9553         fi
9554
9555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9556         sync; sleep 1; sync
9557         local before=$(date +%s)
9558         cancel_lru_locks osc
9559         local after=$(date +%s)
9560         local diff=$((after - before))
9561         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9562
9563         rm -f $DIR/$tfile
9564 }
9565 run_test 80 "Page eviction is equally fast at high offsets too"
9566
9567 test_81a() { # LU-456
9568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9569         remote_ost_nodsh && skip "remote OST with nodsh"
9570
9571         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9572         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9573         do_facet ost1 lctl set_param fail_loc=0x80000228
9574
9575         # write should trigger a retry and success
9576         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9577         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9578         RC=$?
9579         if [ $RC -ne 0 ] ; then
9580                 error "write should success, but failed for $RC"
9581         fi
9582 }
9583 run_test 81a "OST should retry write when get -ENOSPC ==============="
9584
9585 test_81b() { # LU-456
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587         remote_ost_nodsh && skip "remote OST with nodsh"
9588
9589         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9590         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9591         do_facet ost1 lctl set_param fail_loc=0x228
9592
9593         # write should retry several times and return -ENOSPC finally
9594         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9595         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9596         RC=$?
9597         ENOSPC=28
9598         if [ $RC -ne $ENOSPC ] ; then
9599                 error "dd should fail for -ENOSPC, but succeed."
9600         fi
9601 }
9602 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9603
9604 test_99() {
9605         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9606
9607         test_mkdir $DIR/$tdir.cvsroot
9608         chown $RUNAS_ID $DIR/$tdir.cvsroot
9609
9610         cd $TMP
9611         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9612
9613         cd /etc/init.d
9614         # some versions of cvs import exit(1) when asked to import links or
9615         # files they can't read.  ignore those files.
9616         local toignore=$(find . -type l -printf '-I %f\n' -o \
9617                          ! -perm /4 -printf '-I %f\n')
9618         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9619                 $tdir.reposname vtag rtag
9620
9621         cd $DIR
9622         test_mkdir $DIR/$tdir.reposname
9623         chown $RUNAS_ID $DIR/$tdir.reposname
9624         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9625
9626         cd $DIR/$tdir.reposname
9627         $RUNAS touch foo99
9628         $RUNAS cvs add -m 'addmsg' foo99
9629         $RUNAS cvs update
9630         $RUNAS cvs commit -m 'nomsg' foo99
9631         rm -fr $DIR/$tdir.cvsroot
9632 }
9633 run_test 99 "cvs strange file/directory operations"
9634
9635 test_100() {
9636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9637         [[ "$NETTYPE" =~ tcp ]] ||
9638                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9639         remote_ost_nodsh && skip "remote OST with nodsh"
9640         remote_mds_nodsh && skip "remote MDS with nodsh"
9641         remote_servers ||
9642                 skip "useless for local single node setup"
9643
9644         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9645                 [ "$PROT" != "tcp" ] && continue
9646                 RPORT=$(echo $REMOTE | cut -d: -f2)
9647                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9648
9649                 rc=0
9650                 LPORT=`echo $LOCAL | cut -d: -f2`
9651                 if [ $LPORT -ge 1024 ]; then
9652                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9653                         netstat -tna
9654                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9655                 fi
9656         done
9657         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9658 }
9659 run_test 100 "check local port using privileged port ==========="
9660
9661 function get_named_value()
9662 {
9663     local tag=$1
9664
9665     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9666 }
9667
9668 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9669                    awk '/^max_cached_mb/ { print $2 }')
9670
9671 cleanup_101a() {
9672         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9673         trap 0
9674 }
9675
9676 test_101a() {
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678
9679         local s
9680         local discard
9681         local nreads=10000
9682         local cache_limit=32
9683
9684         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9685         trap cleanup_101a EXIT
9686         $LCTL set_param -n llite.*.read_ahead_stats=0
9687         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9688
9689         #
9690         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9691         #
9692         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9693         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9694
9695         discard=0
9696         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9697                    get_named_value 'read.but.discarded'); do
9698                         discard=$(($discard + $s))
9699         done
9700         cleanup_101a
9701
9702         $LCTL get_param osc.*-osc*.rpc_stats
9703         $LCTL get_param llite.*.read_ahead_stats
9704
9705         # Discard is generally zero, but sometimes a few random reads line up
9706         # and trigger larger readahead, which is wasted & leads to discards.
9707         if [[ $(($discard)) -gt $nreads ]]; then
9708                 error "too many ($discard) discarded pages"
9709         fi
9710         rm -f $DIR/$tfile || true
9711 }
9712 run_test 101a "check read-ahead for random reads"
9713
9714 setup_test101bc() {
9715         test_mkdir $DIR/$tdir
9716         local ssize=$1
9717         local FILE_LENGTH=$2
9718         STRIPE_OFFSET=0
9719
9720         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9721
9722         local list=$(comma_list $(osts_nodes))
9723         set_osd_param $list '' read_cache_enable 0
9724         set_osd_param $list '' writethrough_cache_enable 0
9725
9726         trap cleanup_test101bc EXIT
9727         # prepare the read-ahead file
9728         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9729
9730         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9731                                 count=$FILE_SIZE_MB 2> /dev/null
9732
9733 }
9734
9735 cleanup_test101bc() {
9736         trap 0
9737         rm -rf $DIR/$tdir
9738         rm -f $DIR/$tfile
9739
9740         local list=$(comma_list $(osts_nodes))
9741         set_osd_param $list '' read_cache_enable 1
9742         set_osd_param $list '' writethrough_cache_enable 1
9743 }
9744
9745 calc_total() {
9746         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9747 }
9748
9749 ra_check_101() {
9750         local READ_SIZE=$1
9751         local STRIPE_SIZE=$2
9752         local FILE_LENGTH=$3
9753         local RA_INC=1048576
9754         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9755         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9756                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9757         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9758                   get_named_value 'read.but.discarded' | calc_total)
9759         if [[ $DISCARD -gt $discard_limit ]]; then
9760                 $LCTL get_param llite.*.read_ahead_stats
9761                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9762         else
9763                 echo "Read-ahead success for size ${READ_SIZE}"
9764         fi
9765 }
9766
9767 test_101b() {
9768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9770
9771         local STRIPE_SIZE=1048576
9772         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9773
9774         if [ $SLOW == "yes" ]; then
9775                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9776         else
9777                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9778         fi
9779
9780         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9781
9782         # prepare the read-ahead file
9783         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9784         cancel_lru_locks osc
9785         for BIDX in 2 4 8 16 32 64 128 256
9786         do
9787                 local BSIZE=$((BIDX*4096))
9788                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9789                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9790                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9791                 $LCTL set_param -n llite.*.read_ahead_stats=0
9792                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9793                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9794                 cancel_lru_locks osc
9795                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9796         done
9797         cleanup_test101bc
9798         true
9799 }
9800 run_test 101b "check stride-io mode read-ahead ================="
9801
9802 test_101c() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804
9805         local STRIPE_SIZE=1048576
9806         local FILE_LENGTH=$((STRIPE_SIZE*100))
9807         local nreads=10000
9808         local rsize=65536
9809         local osc_rpc_stats
9810
9811         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9812
9813         cancel_lru_locks osc
9814         $LCTL set_param osc.*.rpc_stats=0
9815         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9816         $LCTL get_param osc.*.rpc_stats
9817         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9818                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9819                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9820                 local size
9821
9822                 if [ $lines -le 20 ]; then
9823                         echo "continue debug"
9824                         continue
9825                 fi
9826                 for size in 1 2 4 8; do
9827                         local rpc=$(echo "$stats" |
9828                                     awk '($1 == "'$size':") {print $2; exit; }')
9829                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9830                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9831                 done
9832                 echo "$osc_rpc_stats check passed!"
9833         done
9834         cleanup_test101bc
9835         true
9836 }
9837 run_test 101c "check stripe_size aligned read-ahead"
9838
9839 test_101d() {
9840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9841
9842         local file=$DIR/$tfile
9843         local sz_MB=${FILESIZE_101d:-80}
9844         local ra_MB=${READAHEAD_MB:-40}
9845
9846         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9847         [ $free_MB -lt $sz_MB ] &&
9848                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9849
9850         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9851         $LFS setstripe -c -1 $file || error "setstripe failed"
9852
9853         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9854         echo Cancel LRU locks on lustre client to flush the client cache
9855         cancel_lru_locks osc
9856
9857         echo Disable read-ahead
9858         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9859         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9860         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9861         $LCTL get_param -n llite.*.max_read_ahead_mb
9862
9863         echo "Reading the test file $file with read-ahead disabled"
9864         local sz_KB=$((sz_MB * 1024 / 4))
9865         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9866         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9867         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9868                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9869
9870         echo "Cancel LRU locks on lustre client to flush the client cache"
9871         cancel_lru_locks osc
9872         echo Enable read-ahead with ${ra_MB}MB
9873         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9874
9875         echo "Reading the test file $file with read-ahead enabled"
9876         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9877                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9878
9879         echo "read-ahead disabled time read $raOFF"
9880         echo "read-ahead enabled time read $raON"
9881
9882         rm -f $file
9883         wait_delete_completed
9884
9885         # use awk for this check instead of bash because it handles decimals
9886         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9887                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9888 }
9889 run_test 101d "file read with and without read-ahead enabled"
9890
9891 test_101e() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893
9894         local file=$DIR/$tfile
9895         local size_KB=500  #KB
9896         local count=100
9897         local bsize=1024
9898
9899         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9900         local need_KB=$((count * size_KB))
9901         [[ $free_KB -le $need_KB ]] &&
9902                 skip_env "Need free space $need_KB, have $free_KB"
9903
9904         echo "Creating $count ${size_KB}K test files"
9905         for ((i = 0; i < $count; i++)); do
9906                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9907         done
9908
9909         echo "Cancel LRU locks on lustre client to flush the client cache"
9910         cancel_lru_locks $OSC
9911
9912         echo "Reset readahead stats"
9913         $LCTL set_param -n llite.*.read_ahead_stats=0
9914
9915         for ((i = 0; i < $count; i++)); do
9916                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9917         done
9918
9919         $LCTL get_param llite.*.max_cached_mb
9920         $LCTL get_param llite.*.read_ahead_stats
9921         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9922                      get_named_value 'misses' | calc_total)
9923
9924         for ((i = 0; i < $count; i++)); do
9925                 rm -rf $file.$i 2>/dev/null
9926         done
9927
9928         #10000 means 20% reads are missing in readahead
9929         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9930 }
9931 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9932
9933 test_101f() {
9934         which iozone || skip_env "no iozone installed"
9935
9936         local old_debug=$($LCTL get_param debug)
9937         old_debug=${old_debug#*=}
9938         $LCTL set_param debug="reada mmap"
9939
9940         # create a test file
9941         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9942
9943         echo Cancel LRU locks on lustre client to flush the client cache
9944         cancel_lru_locks osc
9945
9946         echo Reset readahead stats
9947         $LCTL set_param -n llite.*.read_ahead_stats=0
9948
9949         echo mmap read the file with small block size
9950         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9951                 > /dev/null 2>&1
9952
9953         echo checking missing pages
9954         $LCTL get_param llite.*.read_ahead_stats
9955         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9956                         get_named_value 'misses' | calc_total)
9957
9958         $LCTL set_param debug="$old_debug"
9959         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9960         rm -f $DIR/$tfile
9961 }
9962 run_test 101f "check mmap read performance"
9963
9964 test_101g_brw_size_test() {
9965         local mb=$1
9966         local pages=$((mb * 1048576 / PAGE_SIZE))
9967         local file=$DIR/$tfile
9968
9969         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9970                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9971         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9972                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9973                         return 2
9974         done
9975
9976         stack_trap "rm -f $file" EXIT
9977         $LCTL set_param -n osc.*.rpc_stats=0
9978
9979         # 10 RPCs should be enough for the test
9980         local count=10
9981         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9982                 { error "dd write ${mb} MB blocks failed"; return 3; }
9983         cancel_lru_locks osc
9984         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9985                 { error "dd write ${mb} MB blocks failed"; return 4; }
9986
9987         # calculate number of full-sized read and write RPCs
9988         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9989                 sed -n '/pages per rpc/,/^$/p' |
9990                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9991                 END { print reads,writes }'))
9992         # allow one extra full-sized read RPC for async readahead
9993         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9994                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9995         [[ ${rpcs[1]} == $count ]] ||
9996                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9997 }
9998
9999 test_101g() {
10000         remote_ost_nodsh && skip "remote OST with nodsh"
10001
10002         local rpcs
10003         local osts=$(get_facets OST)
10004         local list=$(comma_list $(osts_nodes))
10005         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10006         local brw_size="obdfilter.*.brw_size"
10007
10008         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10009
10010         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10011
10012         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10013                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10014                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10015            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10016                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10017                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10018
10019                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10020                         suffix="M"
10021
10022                 if [[ $orig_mb -lt 16 ]]; then
10023                         save_lustre_params $osts "$brw_size" > $p
10024                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10025                                 error "set 16MB RPC size failed"
10026
10027                         echo "remount client to enable new RPC size"
10028                         remount_client $MOUNT || error "remount_client failed"
10029                 fi
10030
10031                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10032                 # should be able to set brw_size=12, but no rpc_stats for that
10033                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10034         fi
10035
10036         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10037
10038         if [[ $orig_mb -lt 16 ]]; then
10039                 restore_lustre_params < $p
10040                 remount_client $MOUNT || error "remount_client restore failed"
10041         fi
10042
10043         rm -f $p $DIR/$tfile
10044 }
10045 run_test 101g "Big bulk(4/16 MiB) readahead"
10046
10047 test_101h() {
10048         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10049
10050         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10051                 error "dd 70M file failed"
10052         echo Cancel LRU locks on lustre client to flush the client cache
10053         cancel_lru_locks osc
10054
10055         echo "Reset readahead stats"
10056         $LCTL set_param -n llite.*.read_ahead_stats 0
10057
10058         echo "Read 10M of data but cross 64M bundary"
10059         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10060         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10061                      get_named_value 'misses' | calc_total)
10062         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10063         rm -f $p $DIR/$tfile
10064 }
10065 run_test 101h "Readahead should cover current read window"
10066
10067 test_101i() {
10068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10069                 error "dd 10M file failed"
10070
10071         local max_per_file_mb=$($LCTL get_param -n \
10072                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10073         cancel_lru_locks osc
10074         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10075         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10076                 error "set max_read_ahead_per_file_mb to 1 failed"
10077
10078         echo "Reset readahead stats"
10079         $LCTL set_param llite.*.read_ahead_stats=0
10080
10081         dd if=$DIR/$tfile of=/dev/null bs=2M
10082
10083         $LCTL get_param llite.*.read_ahead_stats
10084         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10085                      awk '/misses/ { print $2 }')
10086         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10087         rm -f $DIR/$tfile
10088 }
10089 run_test 101i "allow current readahead to exceed reservation"
10090
10091 test_101j() {
10092         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10093                 error "setstripe $DIR/$tfile failed"
10094         local file_size=$((1048576 * 16))
10095         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10096         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10097
10098         echo Disable read-ahead
10099         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10100
10101         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10102         for blk in $PAGE_SIZE 1048576 $file_size; do
10103                 cancel_lru_locks osc
10104                 echo "Reset readahead stats"
10105                 $LCTL set_param -n llite.*.read_ahead_stats=0
10106                 local count=$(($file_size / $blk))
10107                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10108                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10109                              get_named_value 'failed.to.fast.read' | calc_total)
10110                 $LCTL get_param -n llite.*.read_ahead_stats
10111                 [ $miss -eq $count ] || error "expected $count got $miss"
10112         done
10113
10114         rm -f $p $DIR/$tfile
10115 }
10116 run_test 101j "A complete read block should be submitted when no RA"
10117
10118 setup_test102() {
10119         test_mkdir $DIR/$tdir
10120         chown $RUNAS_ID $DIR/$tdir
10121         STRIPE_SIZE=65536
10122         STRIPE_OFFSET=1
10123         STRIPE_COUNT=$OSTCOUNT
10124         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10125
10126         trap cleanup_test102 EXIT
10127         cd $DIR
10128         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10129         cd $DIR/$tdir
10130         for num in 1 2 3 4; do
10131                 for count in $(seq 1 $STRIPE_COUNT); do
10132                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10133                                 local size=`expr $STRIPE_SIZE \* $num`
10134                                 local file=file"$num-$idx-$count"
10135                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10136                         done
10137                 done
10138         done
10139
10140         cd $DIR
10141         $1 tar cf $TMP/f102.tar $tdir --xattrs
10142 }
10143
10144 cleanup_test102() {
10145         trap 0
10146         rm -f $TMP/f102.tar
10147         rm -rf $DIR/d0.sanity/d102
10148 }
10149
10150 test_102a() {
10151         [ "$UID" != 0 ] && skip "must run as root"
10152         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10153                 skip_env "must have user_xattr"
10154
10155         [ -z "$(which setfattr 2>/dev/null)" ] &&
10156                 skip_env "could not find setfattr"
10157
10158         local testfile=$DIR/$tfile
10159
10160         touch $testfile
10161         echo "set/get xattr..."
10162         setfattr -n trusted.name1 -v value1 $testfile ||
10163                 error "setfattr -n trusted.name1=value1 $testfile failed"
10164         getfattr -n trusted.name1 $testfile 2> /dev/null |
10165           grep "trusted.name1=.value1" ||
10166                 error "$testfile missing trusted.name1=value1"
10167
10168         setfattr -n user.author1 -v author1 $testfile ||
10169                 error "setfattr -n user.author1=author1 $testfile failed"
10170         getfattr -n user.author1 $testfile 2> /dev/null |
10171           grep "user.author1=.author1" ||
10172                 error "$testfile missing trusted.author1=author1"
10173
10174         echo "listxattr..."
10175         setfattr -n trusted.name2 -v value2 $testfile ||
10176                 error "$testfile unable to set trusted.name2"
10177         setfattr -n trusted.name3 -v value3 $testfile ||
10178                 error "$testfile unable to set trusted.name3"
10179         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10180             grep "trusted.name" | wc -l) -eq 3 ] ||
10181                 error "$testfile missing 3 trusted.name xattrs"
10182
10183         setfattr -n user.author2 -v author2 $testfile ||
10184                 error "$testfile unable to set user.author2"
10185         setfattr -n user.author3 -v author3 $testfile ||
10186                 error "$testfile unable to set user.author3"
10187         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10188             grep "user.author" | wc -l) -eq 3 ] ||
10189                 error "$testfile missing 3 user.author xattrs"
10190
10191         echo "remove xattr..."
10192         setfattr -x trusted.name1 $testfile ||
10193                 error "$testfile error deleting trusted.name1"
10194         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10195                 error "$testfile did not delete trusted.name1 xattr"
10196
10197         setfattr -x user.author1 $testfile ||
10198                 error "$testfile error deleting user.author1"
10199         echo "set lustre special xattr ..."
10200         $LFS setstripe -c1 $testfile
10201         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10202                 awk -F "=" '/trusted.lov/ { print $2 }' )
10203         setfattr -n "trusted.lov" -v $lovea $testfile ||
10204                 error "$testfile doesn't ignore setting trusted.lov again"
10205         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10206                 error "$testfile allow setting invalid trusted.lov"
10207         rm -f $testfile
10208 }
10209 run_test 102a "user xattr test =================================="
10210
10211 check_102b_layout() {
10212         local layout="$*"
10213         local testfile=$DIR/$tfile
10214
10215         echo "test layout '$layout'"
10216         $LFS setstripe $layout $testfile || error "setstripe failed"
10217         $LFS getstripe -y $testfile
10218
10219         echo "get/set/list trusted.lov xattr ..." # b=10930
10220         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10221         [[ "$value" =~ "trusted.lov" ]] ||
10222                 error "can't get trusted.lov from $testfile"
10223         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10224                 error "getstripe failed"
10225
10226         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10227
10228         value=$(cut -d= -f2 <<<$value)
10229         # LU-13168: truncated xattr should fail if short lov_user_md header
10230         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10231                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10232         for len in $lens; do
10233                 echo "setfattr $len $testfile.2"
10234                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10235                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10236         done
10237         local stripe_size=$($LFS getstripe -S $testfile.2)
10238         local stripe_count=$($LFS getstripe -c $testfile.2)
10239         [[ $stripe_size -eq 65536 ]] ||
10240                 error "stripe size $stripe_size != 65536"
10241         [[ $stripe_count -eq $stripe_count_orig ]] ||
10242                 error "stripe count $stripe_count != $stripe_count_orig"
10243         rm $testfile $testfile.2
10244 }
10245
10246 test_102b() {
10247         [ -z "$(which setfattr 2>/dev/null)" ] &&
10248                 skip_env "could not find setfattr"
10249         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10250
10251         # check plain layout
10252         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10253
10254         # and also check composite layout
10255         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10256
10257 }
10258 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10259
10260 test_102c() {
10261         [ -z "$(which setfattr 2>/dev/null)" ] &&
10262                 skip_env "could not find setfattr"
10263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10264
10265         # b10930: get/set/list lustre.lov xattr
10266         echo "get/set/list lustre.lov xattr ..."
10267         test_mkdir $DIR/$tdir
10268         chown $RUNAS_ID $DIR/$tdir
10269         local testfile=$DIR/$tdir/$tfile
10270         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10271                 error "setstripe failed"
10272         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10273                 error "getstripe failed"
10274         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10275         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10276
10277         local testfile2=${testfile}2
10278         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10279                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10280
10281         $RUNAS $MCREATE $testfile2
10282         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10283         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10284         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10285         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10286         [ $stripe_count -eq $STRIPECOUNT ] ||
10287                 error "stripe count $stripe_count != $STRIPECOUNT"
10288 }
10289 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10290
10291 compare_stripe_info1() {
10292         local stripe_index_all_zero=true
10293
10294         for num in 1 2 3 4; do
10295                 for count in $(seq 1 $STRIPE_COUNT); do
10296                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10297                                 local size=$((STRIPE_SIZE * num))
10298                                 local file=file"$num-$offset-$count"
10299                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10300                                 [[ $stripe_size -ne $size ]] &&
10301                                     error "$file: size $stripe_size != $size"
10302                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10303                                 # allow fewer stripes to be created, ORI-601
10304                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10305                                     error "$file: count $stripe_count != $count"
10306                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10307                                 [[ $stripe_index -ne 0 ]] &&
10308                                         stripe_index_all_zero=false
10309                         done
10310                 done
10311         done
10312         $stripe_index_all_zero &&
10313                 error "all files are being extracted starting from OST index 0"
10314         return 0
10315 }
10316
10317 have_xattrs_include() {
10318         tar --help | grep -q xattrs-include &&
10319                 echo --xattrs-include="lustre.*"
10320 }
10321
10322 test_102d() {
10323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10324         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10325
10326         XINC=$(have_xattrs_include)
10327         setup_test102
10328         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10329         cd $DIR/$tdir/$tdir
10330         compare_stripe_info1
10331 }
10332 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10333
10334 test_102f() {
10335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10337
10338         XINC=$(have_xattrs_include)
10339         setup_test102
10340         test_mkdir $DIR/$tdir.restore
10341         cd $DIR
10342         tar cf - --xattrs $tdir | tar xf - \
10343                 -C $DIR/$tdir.restore --xattrs $XINC
10344         cd $DIR/$tdir.restore/$tdir
10345         compare_stripe_info1
10346 }
10347 run_test 102f "tar copy files, not keep osts"
10348
10349 grow_xattr() {
10350         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10351                 skip "must have user_xattr"
10352         [ -z "$(which setfattr 2>/dev/null)" ] &&
10353                 skip_env "could not find setfattr"
10354         [ -z "$(which getfattr 2>/dev/null)" ] &&
10355                 skip_env "could not find getfattr"
10356
10357         local xsize=${1:-1024}  # in bytes
10358         local file=$DIR/$tfile
10359         local value="$(generate_string $xsize)"
10360         local xbig=trusted.big
10361         local toobig=$2
10362
10363         touch $file
10364         log "save $xbig on $file"
10365         if [ -z "$toobig" ]
10366         then
10367                 setfattr -n $xbig -v $value $file ||
10368                         error "saving $xbig on $file failed"
10369         else
10370                 setfattr -n $xbig -v $value $file &&
10371                         error "saving $xbig on $file succeeded"
10372                 return 0
10373         fi
10374
10375         local orig=$(get_xattr_value $xbig $file)
10376         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10377
10378         local xsml=trusted.sml
10379         log "save $xsml on $file"
10380         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10381
10382         local new=$(get_xattr_value $xbig $file)
10383         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10384
10385         log "grow $xsml on $file"
10386         setfattr -n $xsml -v "$value" $file ||
10387                 error "growing $xsml on $file failed"
10388
10389         new=$(get_xattr_value $xbig $file)
10390         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10391         log "$xbig still valid after growing $xsml"
10392
10393         rm -f $file
10394 }
10395
10396 test_102h() { # bug 15777
10397         grow_xattr 1024
10398 }
10399 run_test 102h "grow xattr from inside inode to external block"
10400
10401 test_102ha() {
10402         large_xattr_enabled || skip_env "ea_inode feature disabled"
10403
10404         echo "setting xattr of max xattr size: $(max_xattr_size)"
10405         grow_xattr $(max_xattr_size)
10406
10407         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10408         echo "This should fail:"
10409         grow_xattr $(($(max_xattr_size) + 10)) 1
10410 }
10411 run_test 102ha "grow xattr from inside inode to external inode"
10412
10413 test_102i() { # bug 17038
10414         [ -z "$(which getfattr 2>/dev/null)" ] &&
10415                 skip "could not find getfattr"
10416
10417         touch $DIR/$tfile
10418         ln -s $DIR/$tfile $DIR/${tfile}link
10419         getfattr -n trusted.lov $DIR/$tfile ||
10420                 error "lgetxattr on $DIR/$tfile failed"
10421         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10422                 grep -i "no such attr" ||
10423                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10424         rm -f $DIR/$tfile $DIR/${tfile}link
10425 }
10426 run_test 102i "lgetxattr test on symbolic link ============"
10427
10428 test_102j() {
10429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10431
10432         XINC=$(have_xattrs_include)
10433         setup_test102 "$RUNAS"
10434         chown $RUNAS_ID $DIR/$tdir
10435         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10436         cd $DIR/$tdir/$tdir
10437         compare_stripe_info1 "$RUNAS"
10438 }
10439 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10440
10441 test_102k() {
10442         [ -z "$(which setfattr 2>/dev/null)" ] &&
10443                 skip "could not find setfattr"
10444
10445         touch $DIR/$tfile
10446         # b22187 just check that does not crash for regular file.
10447         setfattr -n trusted.lov $DIR/$tfile
10448         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10449         local test_kdir=$DIR/$tdir
10450         test_mkdir $test_kdir
10451         local default_size=$($LFS getstripe -S $test_kdir)
10452         local default_count=$($LFS getstripe -c $test_kdir)
10453         local default_offset=$($LFS getstripe -i $test_kdir)
10454         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10455                 error 'dir setstripe failed'
10456         setfattr -n trusted.lov $test_kdir
10457         local stripe_size=$($LFS getstripe -S $test_kdir)
10458         local stripe_count=$($LFS getstripe -c $test_kdir)
10459         local stripe_offset=$($LFS getstripe -i $test_kdir)
10460         [ $stripe_size -eq $default_size ] ||
10461                 error "stripe size $stripe_size != $default_size"
10462         [ $stripe_count -eq $default_count ] ||
10463                 error "stripe count $stripe_count != $default_count"
10464         [ $stripe_offset -eq $default_offset ] ||
10465                 error "stripe offset $stripe_offset != $default_offset"
10466         rm -rf $DIR/$tfile $test_kdir
10467 }
10468 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10469
10470 test_102l() {
10471         [ -z "$(which getfattr 2>/dev/null)" ] &&
10472                 skip "could not find getfattr"
10473
10474         # LU-532 trusted. xattr is invisible to non-root
10475         local testfile=$DIR/$tfile
10476
10477         touch $testfile
10478
10479         echo "listxattr as user..."
10480         chown $RUNAS_ID $testfile
10481         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10482             grep -q "trusted" &&
10483                 error "$testfile trusted xattrs are user visible"
10484
10485         return 0;
10486 }
10487 run_test 102l "listxattr size test =================================="
10488
10489 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10490         local path=$DIR/$tfile
10491         touch $path
10492
10493         listxattr_size_check $path || error "listattr_size_check $path failed"
10494 }
10495 run_test 102m "Ensure listxattr fails on small bufffer ========"
10496
10497 cleanup_test102
10498
10499 getxattr() { # getxattr path name
10500         # Return the base64 encoding of the value of xattr name on path.
10501         local path=$1
10502         local name=$2
10503
10504         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10505         # file: $path
10506         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10507         #
10508         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10509
10510         getfattr --absolute-names --encoding=base64 --name=$name $path |
10511                 awk -F= -v name=$name '$1 == name {
10512                         print substr($0, index($0, "=") + 1);
10513         }'
10514 }
10515
10516 test_102n() { # LU-4101 mdt: protect internal xattrs
10517         [ -z "$(which setfattr 2>/dev/null)" ] &&
10518                 skip "could not find setfattr"
10519         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10520         then
10521                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10522         fi
10523
10524         local file0=$DIR/$tfile.0
10525         local file1=$DIR/$tfile.1
10526         local xattr0=$TMP/$tfile.0
10527         local xattr1=$TMP/$tfile.1
10528         local namelist="lov lma lmv link fid version som hsm"
10529         local name
10530         local value
10531
10532         rm -rf $file0 $file1 $xattr0 $xattr1
10533         touch $file0 $file1
10534
10535         # Get 'before' xattrs of $file1.
10536         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10537
10538         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10539                 namelist+=" lfsck_namespace"
10540         for name in $namelist; do
10541                 # Try to copy xattr from $file0 to $file1.
10542                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10543
10544                 setfattr --name=trusted.$name --value="$value" $file1 ||
10545                         error "setxattr 'trusted.$name' failed"
10546
10547                 # Try to set a garbage xattr.
10548                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10549
10550                 if [[ x$name == "xlov" ]]; then
10551                         setfattr --name=trusted.lov --value="$value" $file1 &&
10552                         error "setxattr invalid 'trusted.lov' success"
10553                 else
10554                         setfattr --name=trusted.$name --value="$value" $file1 ||
10555                                 error "setxattr invalid 'trusted.$name' failed"
10556                 fi
10557
10558                 # Try to remove the xattr from $file1. We don't care if this
10559                 # appears to succeed or fail, we just don't want there to be
10560                 # any changes or crashes.
10561                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10562         done
10563
10564         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10565         then
10566                 name="lfsck_ns"
10567                 # Try to copy xattr from $file0 to $file1.
10568                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10569
10570                 setfattr --name=trusted.$name --value="$value" $file1 ||
10571                         error "setxattr 'trusted.$name' failed"
10572
10573                 # Try to set a garbage xattr.
10574                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10575
10576                 setfattr --name=trusted.$name --value="$value" $file1 ||
10577                         error "setxattr 'trusted.$name' failed"
10578
10579                 # Try to remove the xattr from $file1. We don't care if this
10580                 # appears to succeed or fail, we just don't want there to be
10581                 # any changes or crashes.
10582                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10583         fi
10584
10585         # Get 'after' xattrs of file1.
10586         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10587
10588         if ! diff $xattr0 $xattr1; then
10589                 error "before and after xattrs of '$file1' differ"
10590         fi
10591
10592         rm -rf $file0 $file1 $xattr0 $xattr1
10593
10594         return 0
10595 }
10596 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10597
10598 test_102p() { # LU-4703 setxattr did not check ownership
10599         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10600                 skip "MDS needs to be at least 2.5.56"
10601
10602         local testfile=$DIR/$tfile
10603
10604         touch $testfile
10605
10606         echo "setfacl as user..."
10607         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10608         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10609
10610         echo "setfattr as user..."
10611         setfacl -m "u:$RUNAS_ID:---" $testfile
10612         $RUNAS setfattr -x system.posix_acl_access $testfile
10613         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10614 }
10615 run_test 102p "check setxattr(2) correctly fails without permission"
10616
10617 test_102q() {
10618         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10619                 skip "MDS needs to be at least 2.6.92"
10620
10621         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10622 }
10623 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10624
10625 test_102r() {
10626         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10627                 skip "MDS needs to be at least 2.6.93"
10628
10629         touch $DIR/$tfile || error "touch"
10630         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10631         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10632         rm $DIR/$tfile || error "rm"
10633
10634         #normal directory
10635         mkdir -p $DIR/$tdir || error "mkdir"
10636         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10637         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10638         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10639                 error "$testfile error deleting user.author1"
10640         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10641                 grep "user.$(basename $tdir)" &&
10642                 error "$tdir did not delete user.$(basename $tdir)"
10643         rmdir $DIR/$tdir || error "rmdir"
10644
10645         #striped directory
10646         test_mkdir $DIR/$tdir
10647         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10648         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10649         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10650                 error "$testfile error deleting user.author1"
10651         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10652                 grep "user.$(basename $tdir)" &&
10653                 error "$tdir did not delete user.$(basename $tdir)"
10654         rmdir $DIR/$tdir || error "rm striped dir"
10655 }
10656 run_test 102r "set EAs with empty values"
10657
10658 test_102s() {
10659         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10660                 skip "MDS needs to be at least 2.11.52"
10661
10662         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10663
10664         save_lustre_params client "llite.*.xattr_cache" > $save
10665
10666         for cache in 0 1; do
10667                 lctl set_param llite.*.xattr_cache=$cache
10668
10669                 rm -f $DIR/$tfile
10670                 touch $DIR/$tfile || error "touch"
10671                 for prefix in lustre security system trusted user; do
10672                         # Note getxattr() may fail with 'Operation not
10673                         # supported' or 'No such attribute' depending
10674                         # on prefix and cache.
10675                         getfattr -n $prefix.n102s $DIR/$tfile &&
10676                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10677                 done
10678         done
10679
10680         restore_lustre_params < $save
10681 }
10682 run_test 102s "getting nonexistent xattrs should fail"
10683
10684 test_102t() {
10685         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10686                 skip "MDS needs to be at least 2.11.52"
10687
10688         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10689
10690         save_lustre_params client "llite.*.xattr_cache" > $save
10691
10692         for cache in 0 1; do
10693                 lctl set_param llite.*.xattr_cache=$cache
10694
10695                 for buf_size in 0 256; do
10696                         rm -f $DIR/$tfile
10697                         touch $DIR/$tfile || error "touch"
10698                         setfattr -n user.multiop $DIR/$tfile
10699                         $MULTIOP $DIR/$tfile oa$buf_size ||
10700                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10701                 done
10702         done
10703
10704         restore_lustre_params < $save
10705 }
10706 run_test 102t "zero length xattr values handled correctly"
10707
10708 run_acl_subtest()
10709 {
10710     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10711     return $?
10712 }
10713
10714 test_103a() {
10715         [ "$UID" != 0 ] && skip "must run as root"
10716         $GSS && skip_env "could not run under gss"
10717         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10718                 skip_env "must have acl enabled"
10719         [ -z "$(which setfacl 2>/dev/null)" ] &&
10720                 skip_env "could not find setfacl"
10721         remote_mds_nodsh && skip "remote MDS with nodsh"
10722
10723         gpasswd -a daemon bin                           # LU-5641
10724         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10725
10726         declare -a identity_old
10727
10728         for num in $(seq $MDSCOUNT); do
10729                 switch_identity $num true || identity_old[$num]=$?
10730         done
10731
10732         SAVE_UMASK=$(umask)
10733         umask 0022
10734         mkdir -p $DIR/$tdir
10735         cd $DIR/$tdir
10736
10737         echo "performing cp ..."
10738         run_acl_subtest cp || error "run_acl_subtest cp failed"
10739         echo "performing getfacl-noacl..."
10740         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10741         echo "performing misc..."
10742         run_acl_subtest misc || error  "misc test failed"
10743         echo "performing permissions..."
10744         run_acl_subtest permissions || error "permissions failed"
10745         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10746         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10747                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10748                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10749         then
10750                 echo "performing permissions xattr..."
10751                 run_acl_subtest permissions_xattr ||
10752                         error "permissions_xattr failed"
10753         fi
10754         echo "performing setfacl..."
10755         run_acl_subtest setfacl || error  "setfacl test failed"
10756
10757         # inheritance test got from HP
10758         echo "performing inheritance..."
10759         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10760         chmod +x make-tree || error "chmod +x failed"
10761         run_acl_subtest inheritance || error "inheritance test failed"
10762         rm -f make-tree
10763
10764         echo "LU-974 ignore umask when acl is enabled..."
10765         run_acl_subtest 974 || error "LU-974 umask test failed"
10766         if [ $MDSCOUNT -ge 2 ]; then
10767                 run_acl_subtest 974_remote ||
10768                         error "LU-974 umask test failed under remote dir"
10769         fi
10770
10771         echo "LU-2561 newly created file is same size as directory..."
10772         if [ "$mds1_FSTYPE" != "zfs" ]; then
10773                 run_acl_subtest 2561 || error "LU-2561 test failed"
10774         else
10775                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10776         fi
10777
10778         run_acl_subtest 4924 || error "LU-4924 test failed"
10779
10780         cd $SAVE_PWD
10781         umask $SAVE_UMASK
10782
10783         for num in $(seq $MDSCOUNT); do
10784                 if [ "${identity_old[$num]}" = 1 ]; then
10785                         switch_identity $num false || identity_old[$num]=$?
10786                 fi
10787         done
10788 }
10789 run_test 103a "acl test"
10790
10791 test_103b() {
10792         declare -a pids
10793         local U
10794
10795         for U in {0..511}; do
10796                 {
10797                 local O=$(printf "%04o" $U)
10798
10799                 umask $(printf "%04o" $((511 ^ $O)))
10800                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10801                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10802
10803                 (( $S == ($O & 0666) )) ||
10804                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10805
10806                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10807                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10808                 (( $S == ($O & 0666) )) ||
10809                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10810
10811                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10812                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10813                 (( $S == ($O & 0666) )) ||
10814                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10815                 rm -f $DIR/$tfile.[smp]$0
10816                 } &
10817                 local pid=$!
10818
10819                 # limit the concurrently running threads to 64. LU-11878
10820                 local idx=$((U % 64))
10821                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10822                 pids[idx]=$pid
10823         done
10824         wait
10825 }
10826 run_test 103b "umask lfs setstripe"
10827
10828 test_103c() {
10829         mkdir -p $DIR/$tdir
10830         cp -rp $DIR/$tdir $DIR/$tdir.bak
10831
10832         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10833                 error "$DIR/$tdir shouldn't contain default ACL"
10834         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10835                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10836         true
10837 }
10838 run_test 103c "'cp -rp' won't set empty acl"
10839
10840 test_103e() {
10841         local numacl
10842         local fileacl
10843         local saved_debug=$($LCTL get_param -n debug)
10844
10845         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10846                 skip "MDS needs to be at least 2.14.0"
10847
10848         large_xattr_enabled || skip_env "ea_inode feature disabled"
10849
10850         mkdir -p $DIR/$tdir
10851         # add big LOV EA to cause reply buffer overflow earlier
10852         $LFS setstripe -C 1000 $DIR/$tdir
10853         lctl set_param mdc.*-mdc*.stats=clear
10854
10855         $LCTL set_param debug=0
10856         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10857         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10858
10859         # add a large number of default ACLs (expect 8000+ for 2.13+)
10860         for U in {2..7000}; do
10861                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10862                         error "Able to add just $U default ACLs"
10863         done
10864         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10865         echo "$numacl default ACLs created"
10866
10867         stat $DIR/$tdir || error "Cannot stat directory"
10868         # check file creation
10869         touch $DIR/$tdir/$tfile ||
10870                 error "failed to create $tfile with $numacl default ACLs"
10871         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10872         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10873         echo "$fileacl ACLs were inherited"
10874         (( $fileacl == $numacl )) ||
10875                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10876         # check that new ACLs creation adds new ACLs to inherited ACLs
10877         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10878                 error "Cannot set new ACL"
10879         numacl=$((numacl + 1))
10880         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10881         (( $fileacl == $numacl )) ||
10882                 error "failed to add new ACL: $fileacl != $numacl as expected"
10883         # adds more ACLs to a file to reach their maximum at 8000+
10884         numacl=0
10885         for U in {20000..25000}; do
10886                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10887                 numacl=$((numacl + 1))
10888         done
10889         echo "Added $numacl more ACLs to the file"
10890         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10891         echo "Total $fileacl ACLs in file"
10892         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10893         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10894         rmdir $DIR/$tdir || error "Cannot remove directory"
10895 }
10896 run_test 103e "inheritance of big amount of default ACLs"
10897
10898 test_104a() {
10899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10900
10901         touch $DIR/$tfile
10902         lfs df || error "lfs df failed"
10903         lfs df -ih || error "lfs df -ih failed"
10904         lfs df -h $DIR || error "lfs df -h $DIR failed"
10905         lfs df -i $DIR || error "lfs df -i $DIR failed"
10906         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10907         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10908
10909         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10910         lctl --device %$OSC deactivate
10911         lfs df || error "lfs df with deactivated OSC failed"
10912         lctl --device %$OSC activate
10913         # wait the osc back to normal
10914         wait_osc_import_ready client ost
10915
10916         lfs df || error "lfs df with reactivated OSC failed"
10917         rm -f $DIR/$tfile
10918 }
10919 run_test 104a "lfs df [-ih] [path] test ========================="
10920
10921 test_104b() {
10922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10923         [ $RUNAS_ID -eq $UID ] &&
10924                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10925
10926         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10927                         grep "Permission denied" | wc -l)))
10928         if [ $denied_cnt -ne 0 ]; then
10929                 error "lfs check servers test failed"
10930         fi
10931 }
10932 run_test 104b "$RUNAS lfs check servers test ===================="
10933
10934 #
10935 # Verify $1 is within range of $2.
10936 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
10937 # $1 is <= 2% of $2. Else Fail.
10938 #
10939 value_in_range() {
10940         # Strip all units (M, G, T)
10941         actual=$(echo $1 | tr -d A-Z)
10942         expect=$(echo $2 | tr -d A-Z)
10943
10944         expect_lo=$(($expect * 98 / 100)) # 2% below
10945         expect_hi=$(($expect * 102 / 100)) # 2% above
10946
10947         # permit 2% drift above and below
10948         (( $actual >= $expect_lo && $actual <= $expect_hi ))
10949 }
10950
10951 test_104c() {
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
10954
10955         local ost_param="osd-zfs.$FSNAME-OST0000."
10956         local mdt_param="osd-zfs.$FSNAME-MDT0000."
10957         local ofacets=$(get_facets OST)
10958         local mfacets=$(get_facets MDS)
10959         local saved_ost_blocks=
10960         local saved_mdt_blocks=
10961
10962         echo "Before recordsize change"
10963         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
10964         df=($(df -h | grep "/mnt/lustre"$))
10965
10966         # For checking.
10967         echo "lfs output : ${lfs_df[*]}"
10968         echo "df  output : ${df[*]}"
10969
10970         for facet in ${ofacets//,/ }; do
10971                 if [ -z $saved_ost_blocks ]; then
10972                         saved_ost_blocks=$(do_facet $facet \
10973                                 lctl get_param -n $ost_param.blocksize)
10974                         echo "OST Blocksize: $saved_ost_blocks"
10975                 fi
10976                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
10977                 do_facet $facet zfs set recordsize=32768 $ost
10978         done
10979
10980         # BS too small. Sufficient for functional testing.
10981         for facet in ${mfacets//,/ }; do
10982                 if [ -z $saved_mdt_blocks ]; then
10983                         saved_mdt_blocks=$(do_facet $facet \
10984                                 lctl get_param -n $mdt_param.blocksize)
10985                         echo "MDT Blocksize: $saved_mdt_blocks"
10986                 fi
10987                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
10988                 do_facet $facet zfs set recordsize=32768 $mdt
10989         done
10990
10991         # Give new values chance to reflect change
10992         sleep 2
10993
10994         echo "After recordsize change"
10995         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
10996         df_after=($(df -h | grep "/mnt/lustre"$))
10997
10998         # For checking.
10999         echo "lfs output : ${lfs_df_after[*]}"
11000         echo "df  output : ${df_after[*]}"
11001
11002         # Verify lfs df
11003         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11004                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11005         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11006                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11007         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11008                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11009
11010         # Verify df
11011         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11012                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11013         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11014                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11015         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11016                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11017
11018         # Restore MDT recordize back to original
11019         for facet in ${mfacets//,/ }; do
11020                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11021                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11022         done
11023
11024         # Restore OST recordize back to original
11025         for facet in ${ofacets//,/ }; do
11026                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11027                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11028         done
11029
11030         return 0
11031 }
11032 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11033
11034 test_105a() {
11035         # doesn't work on 2.4 kernels
11036         touch $DIR/$tfile
11037         if $(flock_is_enabled); then
11038                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11039         else
11040                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11041         fi
11042         rm -f $DIR/$tfile
11043 }
11044 run_test 105a "flock when mounted without -o flock test ========"
11045
11046 test_105b() {
11047         touch $DIR/$tfile
11048         if $(flock_is_enabled); then
11049                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11050         else
11051                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11052         fi
11053         rm -f $DIR/$tfile
11054 }
11055 run_test 105b "fcntl when mounted without -o flock test ========"
11056
11057 test_105c() {
11058         touch $DIR/$tfile
11059         if $(flock_is_enabled); then
11060                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11061         else
11062                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11063         fi
11064         rm -f $DIR/$tfile
11065 }
11066 run_test 105c "lockf when mounted without -o flock test"
11067
11068 test_105d() { # bug 15924
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070
11071         test_mkdir $DIR/$tdir
11072         flock_is_enabled || skip_env "mount w/o flock enabled"
11073         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11074         $LCTL set_param fail_loc=0x80000315
11075         flocks_test 2 $DIR/$tdir
11076 }
11077 run_test 105d "flock race (should not freeze) ========"
11078
11079 test_105e() { # bug 22660 && 22040
11080         flock_is_enabled || skip_env "mount w/o flock enabled"
11081
11082         touch $DIR/$tfile
11083         flocks_test 3 $DIR/$tfile
11084 }
11085 run_test 105e "Two conflicting flocks from same process"
11086
11087 test_106() { #bug 10921
11088         test_mkdir $DIR/$tdir
11089         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11090         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11091 }
11092 run_test 106 "attempt exec of dir followed by chown of that dir"
11093
11094 test_107() {
11095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11096
11097         CDIR=`pwd`
11098         local file=core
11099
11100         cd $DIR
11101         rm -f $file
11102
11103         local save_pattern=$(sysctl -n kernel.core_pattern)
11104         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11105         sysctl -w kernel.core_pattern=$file
11106         sysctl -w kernel.core_uses_pid=0
11107
11108         ulimit -c unlimited
11109         sleep 60 &
11110         SLEEPPID=$!
11111
11112         sleep 1
11113
11114         kill -s 11 $SLEEPPID
11115         wait $SLEEPPID
11116         if [ -e $file ]; then
11117                 size=`stat -c%s $file`
11118                 [ $size -eq 0 ] && error "Fail to create core file $file"
11119         else
11120                 error "Fail to create core file $file"
11121         fi
11122         rm -f $file
11123         sysctl -w kernel.core_pattern=$save_pattern
11124         sysctl -w kernel.core_uses_pid=$save_uses_pid
11125         cd $CDIR
11126 }
11127 run_test 107 "Coredump on SIG"
11128
11129 test_110() {
11130         test_mkdir $DIR/$tdir
11131         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11132         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11133                 error "mkdir with 256 char should fail, but did not"
11134         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11135                 error "create with 255 char failed"
11136         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11137                 error "create with 256 char should fail, but did not"
11138
11139         ls -l $DIR/$tdir
11140         rm -rf $DIR/$tdir
11141 }
11142 run_test 110 "filename length checking"
11143
11144 #
11145 # Purpose: To verify dynamic thread (OSS) creation.
11146 #
11147 test_115() {
11148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11149         remote_ost_nodsh && skip "remote OST with nodsh"
11150
11151         # Lustre does not stop service threads once they are started.
11152         # Reset number of running threads to default.
11153         stopall
11154         setupall
11155
11156         local OSTIO_pre
11157         local save_params="$TMP/sanity-$TESTNAME.parameters"
11158
11159         # Get ll_ost_io count before I/O
11160         OSTIO_pre=$(do_facet ost1 \
11161                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11162         # Exit if lustre is not running (ll_ost_io not running).
11163         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11164
11165         echo "Starting with $OSTIO_pre threads"
11166         local thread_max=$((OSTIO_pre * 2))
11167         local rpc_in_flight=$((thread_max * 2))
11168         # Number of I/O Process proposed to be started.
11169         local nfiles
11170         local facets=$(get_facets OST)
11171
11172         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11173         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11174
11175         # Set in_flight to $rpc_in_flight
11176         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11177                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11178         nfiles=${rpc_in_flight}
11179         # Set ost thread_max to $thread_max
11180         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11181
11182         # 5 Minutes should be sufficient for max number of OSS
11183         # threads(thread_max) to be created.
11184         local timeout=300
11185
11186         # Start I/O.
11187         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11188         test_mkdir $DIR/$tdir
11189         for i in $(seq $nfiles); do
11190                 local file=$DIR/$tdir/${tfile}-$i
11191                 $LFS setstripe -c -1 -i 0 $file
11192                 ($WTL $file $timeout)&
11193         done
11194
11195         # I/O Started - Wait for thread_started to reach thread_max or report
11196         # error if thread_started is more than thread_max.
11197         echo "Waiting for thread_started to reach thread_max"
11198         local thread_started=0
11199         local end_time=$((SECONDS + timeout))
11200
11201         while [ $SECONDS -le $end_time ] ; do
11202                 echo -n "."
11203                 # Get ost i/o thread_started count.
11204                 thread_started=$(do_facet ost1 \
11205                         "$LCTL get_param \
11206                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11207                 # Break out if thread_started is equal/greater than thread_max
11208                 if [[ $thread_started -ge $thread_max ]]; then
11209                         echo ll_ost_io thread_started $thread_started, \
11210                                 equal/greater than thread_max $thread_max
11211                         break
11212                 fi
11213                 sleep 1
11214         done
11215
11216         # Cleanup - We have the numbers, Kill i/o jobs if running.
11217         jobcount=($(jobs -p))
11218         for i in $(seq 0 $((${#jobcount[@]}-1)))
11219         do
11220                 kill -9 ${jobcount[$i]}
11221                 if [ $? -ne 0 ] ; then
11222                         echo Warning: \
11223                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11224                 fi
11225         done
11226
11227         # Cleanup files left by WTL binary.
11228         for i in $(seq $nfiles); do
11229                 local file=$DIR/$tdir/${tfile}-$i
11230                 rm -rf $file
11231                 if [ $? -ne 0 ] ; then
11232                         echo "Warning: Failed to delete file $file"
11233                 fi
11234         done
11235
11236         restore_lustre_params <$save_params
11237         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11238
11239         # Error out if no new thread has started or Thread started is greater
11240         # than thread max.
11241         if [[ $thread_started -le $OSTIO_pre ||
11242                         $thread_started -gt $thread_max ]]; then
11243                 error "ll_ost_io: thread_started $thread_started" \
11244                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11245                       "No new thread started or thread started greater " \
11246                       "than thread_max."
11247         fi
11248 }
11249 run_test 115 "verify dynamic thread creation===================="
11250
11251 free_min_max () {
11252         wait_delete_completed
11253         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11254         echo "OST kbytes available: ${AVAIL[@]}"
11255         MAXV=${AVAIL[0]}
11256         MAXI=0
11257         MINV=${AVAIL[0]}
11258         MINI=0
11259         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11260                 #echo OST $i: ${AVAIL[i]}kb
11261                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11262                         MAXV=${AVAIL[i]}
11263                         MAXI=$i
11264                 fi
11265                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11266                         MINV=${AVAIL[i]}
11267                         MINI=$i
11268                 fi
11269         done
11270         echo "Min free space: OST $MINI: $MINV"
11271         echo "Max free space: OST $MAXI: $MAXV"
11272 }
11273
11274 test_116a() { # was previously test_116()
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11277         remote_mds_nodsh && skip "remote MDS with nodsh"
11278
11279         echo -n "Free space priority "
11280         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11281                 head -n1
11282         declare -a AVAIL
11283         free_min_max
11284
11285         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11286         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11287         trap simple_cleanup_common EXIT
11288
11289         # Check if we need to generate uneven OSTs
11290         test_mkdir -p $DIR/$tdir/OST${MINI}
11291         local FILL=$((MINV / 4))
11292         local DIFF=$((MAXV - MINV))
11293         local DIFF2=$((DIFF * 100 / MINV))
11294
11295         local threshold=$(do_facet $SINGLEMDS \
11296                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11297         threshold=${threshold%%%}
11298         echo -n "Check for uneven OSTs: "
11299         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11300
11301         if [[ $DIFF2 -gt $threshold ]]; then
11302                 echo "ok"
11303                 echo "Don't need to fill OST$MINI"
11304         else
11305                 # generate uneven OSTs. Write 2% over the QOS threshold value
11306                 echo "no"
11307                 DIFF=$((threshold - DIFF2 + 2))
11308                 DIFF2=$((MINV * DIFF / 100))
11309                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11310                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11311                         error "setstripe failed"
11312                 DIFF=$((DIFF2 / 2048))
11313                 i=0
11314                 while [ $i -lt $DIFF ]; do
11315                         i=$((i + 1))
11316                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11317                                 bs=2M count=1 2>/dev/null
11318                         echo -n .
11319                 done
11320                 echo .
11321                 sync
11322                 sleep_maxage
11323                 free_min_max
11324         fi
11325
11326         DIFF=$((MAXV - MINV))
11327         DIFF2=$((DIFF * 100 / MINV))
11328         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11329         if [ $DIFF2 -gt $threshold ]; then
11330                 echo "ok"
11331         else
11332                 echo "failed - QOS mode won't be used"
11333                 simple_cleanup_common
11334                 skip "QOS imbalance criteria not met"
11335         fi
11336
11337         MINI1=$MINI
11338         MINV1=$MINV
11339         MAXI1=$MAXI
11340         MAXV1=$MAXV
11341
11342         # now fill using QOS
11343         $LFS setstripe -c 1 $DIR/$tdir
11344         FILL=$((FILL / 200))
11345         if [ $FILL -gt 600 ]; then
11346                 FILL=600
11347         fi
11348         echo "writing $FILL files to QOS-assigned OSTs"
11349         i=0
11350         while [ $i -lt $FILL ]; do
11351                 i=$((i + 1))
11352                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11353                         count=1 2>/dev/null
11354                 echo -n .
11355         done
11356         echo "wrote $i 200k files"
11357         sync
11358         sleep_maxage
11359
11360         echo "Note: free space may not be updated, so measurements might be off"
11361         free_min_max
11362         DIFF2=$((MAXV - MINV))
11363         echo "free space delta: orig $DIFF final $DIFF2"
11364         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11365         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11366         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11367         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11368         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11369         if [[ $DIFF -gt 0 ]]; then
11370                 FILL=$((DIFF2 * 100 / DIFF - 100))
11371                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11372         fi
11373
11374         # Figure out which files were written where
11375         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11376                awk '/'$MINI1': / {print $2; exit}')
11377         echo $UUID
11378         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11379         echo "$MINC files created on smaller OST $MINI1"
11380         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11381                awk '/'$MAXI1': / {print $2; exit}')
11382         echo $UUID
11383         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11384         echo "$MAXC files created on larger OST $MAXI1"
11385         if [[ $MINC -gt 0 ]]; then
11386                 FILL=$((MAXC * 100 / MINC - 100))
11387                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11388         fi
11389         [[ $MAXC -gt $MINC ]] ||
11390                 error_ignore LU-9 "stripe QOS didn't balance free space"
11391         simple_cleanup_common
11392 }
11393 run_test 116a "stripe QOS: free space balance ==================="
11394
11395 test_116b() { # LU-2093
11396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11397         remote_mds_nodsh && skip "remote MDS with nodsh"
11398
11399 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11400         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11401                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11402         [ -z "$old_rr" ] && skip "no QOS"
11403         do_facet $SINGLEMDS lctl set_param \
11404                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11405         mkdir -p $DIR/$tdir
11406         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11407         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11408         do_facet $SINGLEMDS lctl set_param fail_loc=0
11409         rm -rf $DIR/$tdir
11410         do_facet $SINGLEMDS lctl set_param \
11411                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11412 }
11413 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11414
11415 test_117() # bug 10891
11416 {
11417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11418
11419         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11420         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11421         lctl set_param fail_loc=0x21e
11422         > $DIR/$tfile || error "truncate failed"
11423         lctl set_param fail_loc=0
11424         echo "Truncate succeeded."
11425         rm -f $DIR/$tfile
11426 }
11427 run_test 117 "verify osd extend =========="
11428
11429 NO_SLOW_RESENDCOUNT=4
11430 export OLD_RESENDCOUNT=""
11431 set_resend_count () {
11432         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11433         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11434         lctl set_param -n $PROC_RESENDCOUNT $1
11435         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11436 }
11437
11438 # for reduce test_118* time (b=14842)
11439 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11440
11441 # Reset async IO behavior after error case
11442 reset_async() {
11443         FILE=$DIR/reset_async
11444
11445         # Ensure all OSCs are cleared
11446         $LFS setstripe -c -1 $FILE
11447         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11448         sync
11449         rm $FILE
11450 }
11451
11452 test_118a() #bug 11710
11453 {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455
11456         reset_async
11457
11458         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11459         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11460         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11461
11462         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11463                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11464                 return 1;
11465         fi
11466         rm -f $DIR/$tfile
11467 }
11468 run_test 118a "verify O_SYNC works =========="
11469
11470 test_118b()
11471 {
11472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11473         remote_ost_nodsh && skip "remote OST with nodsh"
11474
11475         reset_async
11476
11477         #define OBD_FAIL_SRV_ENOENT 0x217
11478         set_nodes_failloc "$(osts_nodes)" 0x217
11479         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11480         RC=$?
11481         set_nodes_failloc "$(osts_nodes)" 0
11482         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11483         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11484                     grep -c writeback)
11485
11486         if [[ $RC -eq 0 ]]; then
11487                 error "Must return error due to dropped pages, rc=$RC"
11488                 return 1;
11489         fi
11490
11491         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11492                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11493                 return 1;
11494         fi
11495
11496         echo "Dirty pages not leaked on ENOENT"
11497
11498         # Due to the above error the OSC will issue all RPCs syncronously
11499         # until a subsequent RPC completes successfully without error.
11500         $MULTIOP $DIR/$tfile Ow4096yc
11501         rm -f $DIR/$tfile
11502
11503         return 0
11504 }
11505 run_test 118b "Reclaim dirty pages on fatal error =========="
11506
11507 test_118c()
11508 {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510
11511         # for 118c, restore the original resend count, LU-1940
11512         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11513                                 set_resend_count $OLD_RESENDCOUNT
11514         remote_ost_nodsh && skip "remote OST with nodsh"
11515
11516         reset_async
11517
11518         #define OBD_FAIL_OST_EROFS               0x216
11519         set_nodes_failloc "$(osts_nodes)" 0x216
11520
11521         # multiop should block due to fsync until pages are written
11522         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11523         MULTIPID=$!
11524         sleep 1
11525
11526         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11527                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11528         fi
11529
11530         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11531                     grep -c writeback)
11532         if [[ $WRITEBACK -eq 0 ]]; then
11533                 error "No page in writeback, writeback=$WRITEBACK"
11534         fi
11535
11536         set_nodes_failloc "$(osts_nodes)" 0
11537         wait $MULTIPID
11538         RC=$?
11539         if [[ $RC -ne 0 ]]; then
11540                 error "Multiop fsync failed, rc=$RC"
11541         fi
11542
11543         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11544         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11545                     grep -c writeback)
11546         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11547                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11548         fi
11549
11550         rm -f $DIR/$tfile
11551         echo "Dirty pages flushed via fsync on EROFS"
11552         return 0
11553 }
11554 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11555
11556 # continue to use small resend count to reduce test_118* time (b=14842)
11557 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11558
11559 test_118d()
11560 {
11561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11562         remote_ost_nodsh && skip "remote OST with nodsh"
11563
11564         reset_async
11565
11566         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11567         set_nodes_failloc "$(osts_nodes)" 0x214
11568         # multiop should block due to fsync until pages are written
11569         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11570         MULTIPID=$!
11571         sleep 1
11572
11573         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11574                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11575         fi
11576
11577         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11578                     grep -c writeback)
11579         if [[ $WRITEBACK -eq 0 ]]; then
11580                 error "No page in writeback, writeback=$WRITEBACK"
11581         fi
11582
11583         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11584         set_nodes_failloc "$(osts_nodes)" 0
11585
11586         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11587         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11588                     grep -c writeback)
11589         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11590                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11591         fi
11592
11593         rm -f $DIR/$tfile
11594         echo "Dirty pages gaurenteed flushed via fsync"
11595         return 0
11596 }
11597 run_test 118d "Fsync validation inject a delay of the bulk =========="
11598
11599 test_118f() {
11600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11601
11602         reset_async
11603
11604         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11605         lctl set_param fail_loc=0x8000040a
11606
11607         # Should simulate EINVAL error which is fatal
11608         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11609         RC=$?
11610         if [[ $RC -eq 0 ]]; then
11611                 error "Must return error due to dropped pages, rc=$RC"
11612         fi
11613
11614         lctl set_param fail_loc=0x0
11615
11616         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11617         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11618         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11619                     grep -c writeback)
11620         if [[ $LOCKED -ne 0 ]]; then
11621                 error "Locked pages remain in cache, locked=$LOCKED"
11622         fi
11623
11624         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11625                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11626         fi
11627
11628         rm -f $DIR/$tfile
11629         echo "No pages locked after fsync"
11630
11631         reset_async
11632         return 0
11633 }
11634 run_test 118f "Simulate unrecoverable OSC side error =========="
11635
11636 test_118g() {
11637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11638
11639         reset_async
11640
11641         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11642         lctl set_param fail_loc=0x406
11643
11644         # simulate local -ENOMEM
11645         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11646         RC=$?
11647
11648         lctl set_param fail_loc=0
11649         if [[ $RC -eq 0 ]]; then
11650                 error "Must return error due to dropped pages, rc=$RC"
11651         fi
11652
11653         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11654         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11655         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11656                         grep -c writeback)
11657         if [[ $LOCKED -ne 0 ]]; then
11658                 error "Locked pages remain in cache, locked=$LOCKED"
11659         fi
11660
11661         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11662                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11663         fi
11664
11665         rm -f $DIR/$tfile
11666         echo "No pages locked after fsync"
11667
11668         reset_async
11669         return 0
11670 }
11671 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11672
11673 test_118h() {
11674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11675         remote_ost_nodsh && skip "remote OST with nodsh"
11676
11677         reset_async
11678
11679         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11680         set_nodes_failloc "$(osts_nodes)" 0x20e
11681         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11682         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11683         RC=$?
11684
11685         set_nodes_failloc "$(osts_nodes)" 0
11686         if [[ $RC -eq 0 ]]; then
11687                 error "Must return error due to dropped pages, rc=$RC"
11688         fi
11689
11690         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11691         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11692         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11693                     grep -c writeback)
11694         if [[ $LOCKED -ne 0 ]]; then
11695                 error "Locked pages remain in cache, locked=$LOCKED"
11696         fi
11697
11698         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11699                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11700         fi
11701
11702         rm -f $DIR/$tfile
11703         echo "No pages locked after fsync"
11704
11705         return 0
11706 }
11707 run_test 118h "Verify timeout in handling recoverables errors  =========="
11708
11709 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11710
11711 test_118i() {
11712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11713         remote_ost_nodsh && skip "remote OST with nodsh"
11714
11715         reset_async
11716
11717         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11718         set_nodes_failloc "$(osts_nodes)" 0x20e
11719
11720         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11721         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11722         PID=$!
11723         sleep 5
11724         set_nodes_failloc "$(osts_nodes)" 0
11725
11726         wait $PID
11727         RC=$?
11728         if [[ $RC -ne 0 ]]; then
11729                 error "got error, but should be not, rc=$RC"
11730         fi
11731
11732         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11733         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11734         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11735         if [[ $LOCKED -ne 0 ]]; then
11736                 error "Locked pages remain in cache, locked=$LOCKED"
11737         fi
11738
11739         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11740                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11741         fi
11742
11743         rm -f $DIR/$tfile
11744         echo "No pages locked after fsync"
11745
11746         return 0
11747 }
11748 run_test 118i "Fix error before timeout in recoverable error  =========="
11749
11750 [ "$SLOW" = "no" ] && set_resend_count 4
11751
11752 test_118j() {
11753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11754         remote_ost_nodsh && skip "remote OST with nodsh"
11755
11756         reset_async
11757
11758         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11759         set_nodes_failloc "$(osts_nodes)" 0x220
11760
11761         # return -EIO from OST
11762         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11763         RC=$?
11764         set_nodes_failloc "$(osts_nodes)" 0x0
11765         if [[ $RC -eq 0 ]]; then
11766                 error "Must return error due to dropped pages, rc=$RC"
11767         fi
11768
11769         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11770         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11771         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11772         if [[ $LOCKED -ne 0 ]]; then
11773                 error "Locked pages remain in cache, locked=$LOCKED"
11774         fi
11775
11776         # in recoverable error on OST we want resend and stay until it finished
11777         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11778                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11779         fi
11780
11781         rm -f $DIR/$tfile
11782         echo "No pages locked after fsync"
11783
11784         return 0
11785 }
11786 run_test 118j "Simulate unrecoverable OST side error =========="
11787
11788 test_118k()
11789 {
11790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11791         remote_ost_nodsh && skip "remote OSTs with nodsh"
11792
11793         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11794         set_nodes_failloc "$(osts_nodes)" 0x20e
11795         test_mkdir $DIR/$tdir
11796
11797         for ((i=0;i<10;i++)); do
11798                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11799                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11800                 SLEEPPID=$!
11801                 sleep 0.500s
11802                 kill $SLEEPPID
11803                 wait $SLEEPPID
11804         done
11805
11806         set_nodes_failloc "$(osts_nodes)" 0
11807         rm -rf $DIR/$tdir
11808 }
11809 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11810
11811 test_118l() # LU-646
11812 {
11813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11814
11815         test_mkdir $DIR/$tdir
11816         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11817         rm -rf $DIR/$tdir
11818 }
11819 run_test 118l "fsync dir"
11820
11821 test_118m() # LU-3066
11822 {
11823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11824
11825         test_mkdir $DIR/$tdir
11826         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11827         rm -rf $DIR/$tdir
11828 }
11829 run_test 118m "fdatasync dir ========="
11830
11831 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11832
11833 test_118n()
11834 {
11835         local begin
11836         local end
11837
11838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11839         remote_ost_nodsh && skip "remote OSTs with nodsh"
11840
11841         # Sleep to avoid a cached response.
11842         #define OBD_STATFS_CACHE_SECONDS 1
11843         sleep 2
11844
11845         # Inject a 10 second delay in the OST_STATFS handler.
11846         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11847         set_nodes_failloc "$(osts_nodes)" 0x242
11848
11849         begin=$SECONDS
11850         stat --file-system $MOUNT > /dev/null
11851         end=$SECONDS
11852
11853         set_nodes_failloc "$(osts_nodes)" 0
11854
11855         if ((end - begin > 20)); then
11856             error "statfs took $((end - begin)) seconds, expected 10"
11857         fi
11858 }
11859 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11860
11861 test_119a() # bug 11737
11862 {
11863         BSIZE=$((512 * 1024))
11864         directio write $DIR/$tfile 0 1 $BSIZE
11865         # We ask to read two blocks, which is more than a file size.
11866         # directio will indicate an error when requested and actual
11867         # sizes aren't equeal (a normal situation in this case) and
11868         # print actual read amount.
11869         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11870         if [ "$NOB" != "$BSIZE" ]; then
11871                 error "read $NOB bytes instead of $BSIZE"
11872         fi
11873         rm -f $DIR/$tfile
11874 }
11875 run_test 119a "Short directIO read must return actual read amount"
11876
11877 test_119b() # bug 11737
11878 {
11879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11880
11881         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11883         sync
11884         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11885                 error "direct read failed"
11886         rm -f $DIR/$tfile
11887 }
11888 run_test 119b "Sparse directIO read must return actual read amount"
11889
11890 test_119c() # bug 13099
11891 {
11892         BSIZE=1048576
11893         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11894         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11895         rm -f $DIR/$tfile
11896 }
11897 run_test 119c "Testing for direct read hitting hole"
11898
11899 test_119d() # bug 15950
11900 {
11901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11902
11903         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11904         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11905         BSIZE=1048576
11906         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11907         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11908         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11909         lctl set_param fail_loc=0x40d
11910         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11911         pid_dio=$!
11912         sleep 1
11913         cat $DIR/$tfile > /dev/null &
11914         lctl set_param fail_loc=0
11915         pid_reads=$!
11916         wait $pid_dio
11917         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11918         sleep 2
11919         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11920         error "the read rpcs have not completed in 2s"
11921         rm -f $DIR/$tfile
11922         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11923 }
11924 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11925
11926 test_120a() {
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928         remote_mds_nodsh && skip "remote MDS with nodsh"
11929         test_mkdir -i0 -c1 $DIR/$tdir
11930         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11931                 skip_env "no early lock cancel on server"
11932
11933         lru_resize_disable mdc
11934         lru_resize_disable osc
11935         cancel_lru_locks mdc
11936         # asynchronous object destroy at MDT could cause bl ast to client
11937         cancel_lru_locks osc
11938
11939         stat $DIR/$tdir > /dev/null
11940         can1=$(do_facet mds1 \
11941                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11942                awk '/ldlm_cancel/ {print $2}')
11943         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11944                awk '/ldlm_bl_callback/ {print $2}')
11945         test_mkdir -i0 -c1 $DIR/$tdir/d1
11946         can2=$(do_facet mds1 \
11947                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11948                awk '/ldlm_cancel/ {print $2}')
11949         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11950                awk '/ldlm_bl_callback/ {print $2}')
11951         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11952         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11953         lru_resize_enable mdc
11954         lru_resize_enable osc
11955 }
11956 run_test 120a "Early Lock Cancel: mkdir test"
11957
11958 test_120b() {
11959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11960         remote_mds_nodsh && skip "remote MDS with nodsh"
11961         test_mkdir $DIR/$tdir
11962         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11963                 skip_env "no early lock cancel on server"
11964
11965         lru_resize_disable mdc
11966         lru_resize_disable osc
11967         cancel_lru_locks mdc
11968         stat $DIR/$tdir > /dev/null
11969         can1=$(do_facet $SINGLEMDS \
11970                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11971                awk '/ldlm_cancel/ {print $2}')
11972         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11973                awk '/ldlm_bl_callback/ {print $2}')
11974         touch $DIR/$tdir/f1
11975         can2=$(do_facet $SINGLEMDS \
11976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11977                awk '/ldlm_cancel/ {print $2}')
11978         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11979                awk '/ldlm_bl_callback/ {print $2}')
11980         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11981         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11982         lru_resize_enable mdc
11983         lru_resize_enable osc
11984 }
11985 run_test 120b "Early Lock Cancel: create test"
11986
11987 test_120c() {
11988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11989         remote_mds_nodsh && skip "remote MDS with nodsh"
11990         test_mkdir -i0 -c1 $DIR/$tdir
11991         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11992                 skip "no early lock cancel on server"
11993
11994         lru_resize_disable mdc
11995         lru_resize_disable osc
11996         test_mkdir -i0 -c1 $DIR/$tdir/d1
11997         test_mkdir -i0 -c1 $DIR/$tdir/d2
11998         touch $DIR/$tdir/d1/f1
11999         cancel_lru_locks mdc
12000         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12001         can1=$(do_facet mds1 \
12002                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12003                awk '/ldlm_cancel/ {print $2}')
12004         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12005                awk '/ldlm_bl_callback/ {print $2}')
12006         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12007         can2=$(do_facet mds1 \
12008                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12009                awk '/ldlm_cancel/ {print $2}')
12010         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12011                awk '/ldlm_bl_callback/ {print $2}')
12012         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12013         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12014         lru_resize_enable mdc
12015         lru_resize_enable osc
12016 }
12017 run_test 120c "Early Lock Cancel: link test"
12018
12019 test_120d() {
12020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12021         remote_mds_nodsh && skip "remote MDS with nodsh"
12022         test_mkdir -i0 -c1 $DIR/$tdir
12023         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12024                 skip_env "no early lock cancel on server"
12025
12026         lru_resize_disable mdc
12027         lru_resize_disable osc
12028         touch $DIR/$tdir
12029         cancel_lru_locks mdc
12030         stat $DIR/$tdir > /dev/null
12031         can1=$(do_facet mds1 \
12032                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12033                awk '/ldlm_cancel/ {print $2}')
12034         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12035                awk '/ldlm_bl_callback/ {print $2}')
12036         chmod a+x $DIR/$tdir
12037         can2=$(do_facet mds1 \
12038                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12039                awk '/ldlm_cancel/ {print $2}')
12040         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12041                awk '/ldlm_bl_callback/ {print $2}')
12042         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12043         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12044         lru_resize_enable mdc
12045         lru_resize_enable osc
12046 }
12047 run_test 120d "Early Lock Cancel: setattr test"
12048
12049 test_120e() {
12050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12051         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12052                 skip_env "no early lock cancel on server"
12053         remote_mds_nodsh && skip "remote MDS with nodsh"
12054
12055         local dlmtrace_set=false
12056
12057         test_mkdir -i0 -c1 $DIR/$tdir
12058         lru_resize_disable mdc
12059         lru_resize_disable osc
12060         ! $LCTL get_param debug | grep -q dlmtrace &&
12061                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12062         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12063         cancel_lru_locks mdc
12064         cancel_lru_locks osc
12065         dd if=$DIR/$tdir/f1 of=/dev/null
12066         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12067         # XXX client can not do early lock cancel of OST lock
12068         # during unlink (LU-4206), so cancel osc lock now.
12069         sleep 2
12070         cancel_lru_locks osc
12071         can1=$(do_facet mds1 \
12072                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12073                awk '/ldlm_cancel/ {print $2}')
12074         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12075                awk '/ldlm_bl_callback/ {print $2}')
12076         unlink $DIR/$tdir/f1
12077         sleep 5
12078         can2=$(do_facet mds1 \
12079                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12080                awk '/ldlm_cancel/ {print $2}')
12081         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12082                awk '/ldlm_bl_callback/ {print $2}')
12083         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12084                 $LCTL dk $TMP/cancel.debug.txt
12085         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12086                 $LCTL dk $TMP/blocking.debug.txt
12087         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12088         lru_resize_enable mdc
12089         lru_resize_enable osc
12090 }
12091 run_test 120e "Early Lock Cancel: unlink test"
12092
12093 test_120f() {
12094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12095         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12096                 skip_env "no early lock cancel on server"
12097         remote_mds_nodsh && skip "remote MDS with nodsh"
12098
12099         test_mkdir -i0 -c1 $DIR/$tdir
12100         lru_resize_disable mdc
12101         lru_resize_disable osc
12102         test_mkdir -i0 -c1 $DIR/$tdir/d1
12103         test_mkdir -i0 -c1 $DIR/$tdir/d2
12104         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12105         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12106         cancel_lru_locks mdc
12107         cancel_lru_locks osc
12108         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12109         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12110         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12111         # XXX client can not do early lock cancel of OST lock
12112         # during rename (LU-4206), so cancel osc lock now.
12113         sleep 2
12114         cancel_lru_locks osc
12115         can1=$(do_facet mds1 \
12116                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12117                awk '/ldlm_cancel/ {print $2}')
12118         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12119                awk '/ldlm_bl_callback/ {print $2}')
12120         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12121         sleep 5
12122         can2=$(do_facet mds1 \
12123                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12124                awk '/ldlm_cancel/ {print $2}')
12125         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12126                awk '/ldlm_bl_callback/ {print $2}')
12127         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12128         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12129         lru_resize_enable mdc
12130         lru_resize_enable osc
12131 }
12132 run_test 120f "Early Lock Cancel: rename test"
12133
12134 test_120g() {
12135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12136         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12137                 skip_env "no early lock cancel on server"
12138         remote_mds_nodsh && skip "remote MDS with nodsh"
12139
12140         lru_resize_disable mdc
12141         lru_resize_disable osc
12142         count=10000
12143         echo create $count files
12144         test_mkdir $DIR/$tdir
12145         cancel_lru_locks mdc
12146         cancel_lru_locks osc
12147         t0=$(date +%s)
12148
12149         can0=$(do_facet $SINGLEMDS \
12150                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12151                awk '/ldlm_cancel/ {print $2}')
12152         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12153                awk '/ldlm_bl_callback/ {print $2}')
12154         createmany -o $DIR/$tdir/f $count
12155         sync
12156         can1=$(do_facet $SINGLEMDS \
12157                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12158                awk '/ldlm_cancel/ {print $2}')
12159         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12160                awk '/ldlm_bl_callback/ {print $2}')
12161         t1=$(date +%s)
12162         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12163         echo rm $count files
12164         rm -r $DIR/$tdir
12165         sync
12166         can2=$(do_facet $SINGLEMDS \
12167                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12168                awk '/ldlm_cancel/ {print $2}')
12169         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12170                awk '/ldlm_bl_callback/ {print $2}')
12171         t2=$(date +%s)
12172         echo total: $count removes in $((t2-t1))
12173         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12174         sleep 2
12175         # wait for commitment of removal
12176         lru_resize_enable mdc
12177         lru_resize_enable osc
12178 }
12179 run_test 120g "Early Lock Cancel: performance test"
12180
12181 test_121() { #bug #10589
12182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12183
12184         rm -rf $DIR/$tfile
12185         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12186 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12187         lctl set_param fail_loc=0x310
12188         cancel_lru_locks osc > /dev/null
12189         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12190         lctl set_param fail_loc=0
12191         [[ $reads -eq $writes ]] ||
12192                 error "read $reads blocks, must be $writes blocks"
12193 }
12194 run_test 121 "read cancel race ========="
12195
12196 test_123a_base() { # was test 123, statahead(bug 11401)
12197         local lsx="$1"
12198
12199         SLOWOK=0
12200         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12201                 log "testing UP system. Performance may be lower than expected."
12202                 SLOWOK=1
12203         fi
12204
12205         rm -rf $DIR/$tdir
12206         test_mkdir $DIR/$tdir
12207         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12208         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12209         MULT=10
12210         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12211                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12212
12213                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12214                 lctl set_param -n llite.*.statahead_max 0
12215                 lctl get_param llite.*.statahead_max
12216                 cancel_lru_locks mdc
12217                 cancel_lru_locks osc
12218                 stime=$(date +%s)
12219                 time $lsx $DIR/$tdir | wc -l
12220                 etime=$(date +%s)
12221                 delta=$((etime - stime))
12222                 log "$lsx $i files without statahead: $delta sec"
12223                 lctl set_param llite.*.statahead_max=$max
12224
12225                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12226                         grep "statahead wrong:" | awk '{print $3}')
12227                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12228                 cancel_lru_locks mdc
12229                 cancel_lru_locks osc
12230                 stime=$(date +%s)
12231                 time $lsx $DIR/$tdir | wc -l
12232                 etime=$(date +%s)
12233                 delta_sa=$((etime - stime))
12234                 log "$lsx $i files with statahead: $delta_sa sec"
12235                 lctl get_param -n llite.*.statahead_stats
12236                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12237                         grep "statahead wrong:" | awk '{print $3}')
12238
12239                 [[ $swrong -lt $ewrong ]] &&
12240                         log "statahead was stopped, maybe too many locks held!"
12241                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12242
12243                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12244                         max=$(lctl get_param -n llite.*.statahead_max |
12245                                 head -n 1)
12246                         lctl set_param -n llite.*.statahead_max 0
12247                         lctl get_param llite.*.statahead_max
12248                         cancel_lru_locks mdc
12249                         cancel_lru_locks osc
12250                         stime=$(date +%s)
12251                         time $lsx $DIR/$tdir | wc -l
12252                         etime=$(date +%s)
12253                         delta=$((etime - stime))
12254                         log "$lsx $i files again without statahead: $delta sec"
12255                         lctl set_param llite.*.statahead_max=$max
12256                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12257                                 if [  $SLOWOK -eq 0 ]; then
12258                                         error "$lsx $i files is slower with statahead!"
12259                                 else
12260                                         log "$lsx $i files is slower with statahead!"
12261                                 fi
12262                                 break
12263                         fi
12264                 fi
12265
12266                 [ $delta -gt 20 ] && break
12267                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12268                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12269         done
12270         log "$lsx done"
12271
12272         stime=$(date +%s)
12273         rm -r $DIR/$tdir
12274         sync
12275         etime=$(date +%s)
12276         delta=$((etime - stime))
12277         log "rm -r $DIR/$tdir/: $delta seconds"
12278         log "rm done"
12279         lctl get_param -n llite.*.statahead_stats
12280 }
12281
12282 test_123aa() {
12283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12284
12285         test_123a_base "ls -l"
12286 }
12287 run_test 123aa "verify statahead work"
12288
12289 test_123ab() {
12290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12291
12292         statx_supported || skip_env "Test must be statx() syscall supported"
12293
12294         test_123a_base "$STATX -l"
12295 }
12296 run_test 123ab "verify statahead work by using statx"
12297
12298 test_123ac() {
12299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12300
12301         statx_supported || skip_env "Test must be statx() syscall supported"
12302
12303         local rpcs_before
12304         local rpcs_after
12305         local agl_before
12306         local agl_after
12307
12308         cancel_lru_locks $OSC
12309         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12310         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12311                 awk '/agl.total:/ {print $3}')
12312         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12313         test_123a_base "$STATX --cached=always -D"
12314         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12315                 awk '/agl.total:/ {print $3}')
12316         [ $agl_before -eq $agl_after ] ||
12317                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12318         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12319         [ $rpcs_after -eq $rpcs_before ] ||
12320                 error "$STATX should not send glimpse RPCs to $OSC"
12321 }
12322 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12323
12324 test_123b () { # statahead(bug 15027)
12325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12326
12327         test_mkdir $DIR/$tdir
12328         createmany -o $DIR/$tdir/$tfile-%d 1000
12329
12330         cancel_lru_locks mdc
12331         cancel_lru_locks osc
12332
12333 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12334         lctl set_param fail_loc=0x80000803
12335         ls -lR $DIR/$tdir > /dev/null
12336         log "ls done"
12337         lctl set_param fail_loc=0x0
12338         lctl get_param -n llite.*.statahead_stats
12339         rm -r $DIR/$tdir
12340         sync
12341
12342 }
12343 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12344
12345 test_123c() {
12346         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12347
12348         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12349         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12350         touch $DIR/$tdir.1/{1..3}
12351         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12352
12353         remount_client $MOUNT
12354
12355         $MULTIOP $DIR/$tdir.0 Q
12356
12357         # let statahead to complete
12358         ls -l $DIR/$tdir.0 > /dev/null
12359
12360         testid=$(echo $TESTNAME | tr '_' ' ')
12361         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12362                 error "statahead warning" || true
12363 }
12364 run_test 123c "Can not initialize inode warning on DNE statahead"
12365
12366 test_124a() {
12367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12368         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12369                 skip_env "no lru resize on server"
12370
12371         local NR=2000
12372
12373         test_mkdir $DIR/$tdir
12374
12375         log "create $NR files at $DIR/$tdir"
12376         createmany -o $DIR/$tdir/f $NR ||
12377                 error "failed to create $NR files in $DIR/$tdir"
12378
12379         cancel_lru_locks mdc
12380         ls -l $DIR/$tdir > /dev/null
12381
12382         local NSDIR=""
12383         local LRU_SIZE=0
12384         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12385                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12386                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12387                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12388                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12389                         log "NSDIR=$NSDIR"
12390                         log "NS=$(basename $NSDIR)"
12391                         break
12392                 fi
12393         done
12394
12395         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12396                 skip "Not enough cached locks created!"
12397         fi
12398         log "LRU=$LRU_SIZE"
12399
12400         local SLEEP=30
12401
12402         # We know that lru resize allows one client to hold $LIMIT locks
12403         # for 10h. After that locks begin to be killed by client.
12404         local MAX_HRS=10
12405         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12406         log "LIMIT=$LIMIT"
12407         if [ $LIMIT -lt $LRU_SIZE ]; then
12408                 skip "Limit is too small $LIMIT"
12409         fi
12410
12411         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12412         # killing locks. Some time was spent for creating locks. This means
12413         # that up to the moment of sleep finish we must have killed some of
12414         # them (10-100 locks). This depends on how fast ther were created.
12415         # Many of them were touched in almost the same moment and thus will
12416         # be killed in groups.
12417         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12418
12419         # Use $LRU_SIZE_B here to take into account real number of locks
12420         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12421         local LRU_SIZE_B=$LRU_SIZE
12422         log "LVF=$LVF"
12423         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12424         log "OLD_LVF=$OLD_LVF"
12425         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12426
12427         # Let's make sure that we really have some margin. Client checks
12428         # cached locks every 10 sec.
12429         SLEEP=$((SLEEP+20))
12430         log "Sleep ${SLEEP} sec"
12431         local SEC=0
12432         while ((SEC<$SLEEP)); do
12433                 echo -n "..."
12434                 sleep 5
12435                 SEC=$((SEC+5))
12436                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12437                 echo -n "$LRU_SIZE"
12438         done
12439         echo ""
12440         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12441         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12442
12443         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12444                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12445                 unlinkmany $DIR/$tdir/f $NR
12446                 return
12447         }
12448
12449         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12450         log "unlink $NR files at $DIR/$tdir"
12451         unlinkmany $DIR/$tdir/f $NR
12452 }
12453 run_test 124a "lru resize ======================================="
12454
12455 get_max_pool_limit()
12456 {
12457         local limit=$($LCTL get_param \
12458                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12459         local max=0
12460         for l in $limit; do
12461                 if [[ $l -gt $max ]]; then
12462                         max=$l
12463                 fi
12464         done
12465         echo $max
12466 }
12467
12468 test_124b() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12471                 skip_env "no lru resize on server"
12472
12473         LIMIT=$(get_max_pool_limit)
12474
12475         NR=$(($(default_lru_size)*20))
12476         if [[ $NR -gt $LIMIT ]]; then
12477                 log "Limit lock number by $LIMIT locks"
12478                 NR=$LIMIT
12479         fi
12480
12481         IFree=$(mdsrate_inodes_available)
12482         if [ $IFree -lt $NR ]; then
12483                 log "Limit lock number by $IFree inodes"
12484                 NR=$IFree
12485         fi
12486
12487         lru_resize_disable mdc
12488         test_mkdir -p $DIR/$tdir/disable_lru_resize
12489
12490         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12491         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12492         cancel_lru_locks mdc
12493         stime=`date +%s`
12494         PID=""
12495         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12496         PID="$PID $!"
12497         sleep 2
12498         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12499         PID="$PID $!"
12500         sleep 2
12501         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12502         PID="$PID $!"
12503         wait $PID
12504         etime=`date +%s`
12505         nolruresize_delta=$((etime-stime))
12506         log "ls -la time: $nolruresize_delta seconds"
12507         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12508         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12509
12510         lru_resize_enable mdc
12511         test_mkdir -p $DIR/$tdir/enable_lru_resize
12512
12513         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12514         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12515         cancel_lru_locks mdc
12516         stime=`date +%s`
12517         PID=""
12518         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12519         PID="$PID $!"
12520         sleep 2
12521         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12522         PID="$PID $!"
12523         sleep 2
12524         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12525         PID="$PID $!"
12526         wait $PID
12527         etime=`date +%s`
12528         lruresize_delta=$((etime-stime))
12529         log "ls -la time: $lruresize_delta seconds"
12530         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12531
12532         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12533                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12534         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12535                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12536         else
12537                 log "lru resize performs the same with no lru resize"
12538         fi
12539         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12540 }
12541 run_test 124b "lru resize (performance test) ======================="
12542
12543 test_124c() {
12544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12545         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12546                 skip_env "no lru resize on server"
12547
12548         # cache ununsed locks on client
12549         local nr=100
12550         cancel_lru_locks mdc
12551         test_mkdir $DIR/$tdir
12552         createmany -o $DIR/$tdir/f $nr ||
12553                 error "failed to create $nr files in $DIR/$tdir"
12554         ls -l $DIR/$tdir > /dev/null
12555
12556         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12557         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12558         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12559         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12560         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12561
12562         # set lru_max_age to 1 sec
12563         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12564         echo "sleep $((recalc_p * 2)) seconds..."
12565         sleep $((recalc_p * 2))
12566
12567         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12568         # restore lru_max_age
12569         $LCTL set_param -n $nsdir.lru_max_age $max_age
12570         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12571         unlinkmany $DIR/$tdir/f $nr
12572 }
12573 run_test 124c "LRUR cancel very aged locks"
12574
12575 test_124d() {
12576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12577         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12578                 skip_env "no lru resize on server"
12579
12580         # cache ununsed locks on client
12581         local nr=100
12582
12583         lru_resize_disable mdc
12584         stack_trap "lru_resize_enable mdc" EXIT
12585
12586         cancel_lru_locks mdc
12587
12588         # asynchronous object destroy at MDT could cause bl ast to client
12589         test_mkdir $DIR/$tdir
12590         createmany -o $DIR/$tdir/f $nr ||
12591                 error "failed to create $nr files in $DIR/$tdir"
12592         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12593
12594         ls -l $DIR/$tdir > /dev/null
12595
12596         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12597         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12598         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12599         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12600
12601         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12602
12603         # set lru_max_age to 1 sec
12604         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12605         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12606
12607         echo "sleep $((recalc_p * 2)) seconds..."
12608         sleep $((recalc_p * 2))
12609
12610         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12611
12612         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12613 }
12614 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12615
12616 test_125() { # 13358
12617         $LCTL get_param -n llite.*.client_type | grep -q local ||
12618                 skip "must run as local client"
12619         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12620                 skip_env "must have acl enabled"
12621         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12622
12623         test_mkdir $DIR/$tdir
12624         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12625         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12626         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12627 }
12628 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12629
12630 test_126() { # bug 12829/13455
12631         $GSS && skip_env "must run as gss disabled"
12632         $LCTL get_param -n llite.*.client_type | grep -q local ||
12633                 skip "must run as local client"
12634         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12635
12636         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12637         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12638         rm -f $DIR/$tfile
12639         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12640 }
12641 run_test 126 "check that the fsgid provided by the client is taken into account"
12642
12643 test_127a() { # bug 15521
12644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12645         local name count samp unit min max sum sumsq
12646
12647         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12648         echo "stats before reset"
12649         $LCTL get_param osc.*.stats
12650         $LCTL set_param osc.*.stats=0
12651         local fsize=$((2048 * 1024))
12652
12653         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12654         cancel_lru_locks osc
12655         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12656
12657         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12658         stack_trap "rm -f $TMP/$tfile.tmp"
12659         while read name count samp unit min max sum sumsq; do
12660                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12661                 [ ! $min ] && error "Missing min value for $name proc entry"
12662                 eval $name=$count || error "Wrong proc format"
12663
12664                 case $name in
12665                 read_bytes|write_bytes)
12666                         [[ "$unit" =~ "bytes" ]] ||
12667                                 error "unit is not 'bytes': $unit"
12668                         (( $min >= 4096 )) || error "min is too small: $min"
12669                         (( $min <= $fsize )) || error "min is too big: $min"
12670                         (( $max >= 4096 )) || error "max is too small: $max"
12671                         (( $max <= $fsize )) || error "max is too big: $max"
12672                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12673                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12674                                 error "sumsquare is too small: $sumsq"
12675                         (( $sumsq <= $fsize * $fsize )) ||
12676                                 error "sumsquare is too big: $sumsq"
12677                         ;;
12678                 ost_read|ost_write)
12679                         [[ "$unit" =~ "usec" ]] ||
12680                                 error "unit is not 'usec': $unit"
12681                         ;;
12682                 *)      ;;
12683                 esac
12684         done < $DIR/$tfile.tmp
12685
12686         #check that we actually got some stats
12687         [ "$read_bytes" ] || error "Missing read_bytes stats"
12688         [ "$write_bytes" ] || error "Missing write_bytes stats"
12689         [ "$read_bytes" != 0 ] || error "no read done"
12690         [ "$write_bytes" != 0 ] || error "no write done"
12691 }
12692 run_test 127a "verify the client stats are sane"
12693
12694 test_127b() { # bug LU-333
12695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12696         local name count samp unit min max sum sumsq
12697
12698         echo "stats before reset"
12699         $LCTL get_param llite.*.stats
12700         $LCTL set_param llite.*.stats=0
12701
12702         # perform 2 reads and writes so MAX is different from SUM.
12703         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12704         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12705         cancel_lru_locks osc
12706         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12707         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12708
12709         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12710         stack_trap "rm -f $TMP/$tfile.tmp"
12711         while read name count samp unit min max sum sumsq; do
12712                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12713                 eval $name=$count || error "Wrong proc format"
12714
12715                 case $name in
12716                 read_bytes|write_bytes)
12717                         [[ "$unit" =~ "bytes" ]] ||
12718                                 error "unit is not 'bytes': $unit"
12719                         (( $count == 2 )) || error "count is not 2: $count"
12720                         (( $min == $PAGE_SIZE )) ||
12721                                 error "min is not $PAGE_SIZE: $min"
12722                         (( $max == $PAGE_SIZE )) ||
12723                                 error "max is not $PAGE_SIZE: $max"
12724                         (( $sum == $PAGE_SIZE * 2 )) ||
12725                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12726                         ;;
12727                 read|write)
12728                         [[ "$unit" =~ "usec" ]] ||
12729                                 error "unit is not 'usec': $unit"
12730                         ;;
12731                 *)      ;;
12732                 esac
12733         done < $TMP/$tfile.tmp
12734
12735         #check that we actually got some stats
12736         [ "$read_bytes" ] || error "Missing read_bytes stats"
12737         [ "$write_bytes" ] || error "Missing write_bytes stats"
12738         [ "$read_bytes" != 0 ] || error "no read done"
12739         [ "$write_bytes" != 0 ] || error "no write done"
12740 }
12741 run_test 127b "verify the llite client stats are sane"
12742
12743 test_127c() { # LU-12394
12744         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12745         local size
12746         local bsize
12747         local reads
12748         local writes
12749         local count
12750
12751         $LCTL set_param llite.*.extents_stats=1
12752         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12753
12754         # Use two stripes so there is enough space in default config
12755         $LFS setstripe -c 2 $DIR/$tfile
12756
12757         # Extent stats start at 0-4K and go in power of two buckets
12758         # LL_HIST_START = 12 --> 2^12 = 4K
12759         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12760         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12761         # small configs
12762         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12763                 do
12764                 # Write and read, 2x each, second time at a non-zero offset
12765                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12766                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12767                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12768                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12769                 rm -f $DIR/$tfile
12770         done
12771
12772         $LCTL get_param llite.*.extents_stats
12773
12774         count=2
12775         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12776                 do
12777                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12778                                 grep -m 1 $bsize)
12779                 reads=$(echo $bucket | awk '{print $5}')
12780                 writes=$(echo $bucket | awk '{print $9}')
12781                 [ "$reads" -eq $count ] ||
12782                         error "$reads reads in < $bsize bucket, expect $count"
12783                 [ "$writes" -eq $count ] ||
12784                         error "$writes writes in < $bsize bucket, expect $count"
12785         done
12786
12787         # Test mmap write and read
12788         $LCTL set_param llite.*.extents_stats=c
12789         size=512
12790         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12791         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12792         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12793
12794         $LCTL get_param llite.*.extents_stats
12795
12796         count=$(((size*1024) / PAGE_SIZE))
12797
12798         bsize=$((2 * PAGE_SIZE / 1024))K
12799
12800         bucket=$($LCTL get_param -n llite.*.extents_stats |
12801                         grep -m 1 $bsize)
12802         reads=$(echo $bucket | awk '{print $5}')
12803         writes=$(echo $bucket | awk '{print $9}')
12804         # mmap writes fault in the page first, creating an additonal read
12805         [ "$reads" -eq $((2 * count)) ] ||
12806                 error "$reads reads in < $bsize bucket, expect $count"
12807         [ "$writes" -eq $count ] ||
12808                 error "$writes writes in < $bsize bucket, expect $count"
12809 }
12810 run_test 127c "test llite extent stats with regular & mmap i/o"
12811
12812 test_128() { # bug 15212
12813         touch $DIR/$tfile
12814         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12815                 find $DIR/$tfile
12816                 find $DIR/$tfile
12817         EOF
12818
12819         result=$(grep error $TMP/$tfile.log)
12820         rm -f $DIR/$tfile $TMP/$tfile.log
12821         [ -z "$result" ] ||
12822                 error "consecutive find's under interactive lfs failed"
12823 }
12824 run_test 128 "interactive lfs for 2 consecutive find's"
12825
12826 set_dir_limits () {
12827         local mntdev
12828         local canondev
12829         local node
12830
12831         local ldproc=/proc/fs/ldiskfs
12832         local facets=$(get_facets MDS)
12833
12834         for facet in ${facets//,/ }; do
12835                 canondev=$(ldiskfs_canon \
12836                            *.$(convert_facet2label $facet).mntdev $facet)
12837                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12838                         ldproc=/sys/fs/ldiskfs
12839                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12840                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12841         done
12842 }
12843
12844 check_mds_dmesg() {
12845         local facets=$(get_facets MDS)
12846         for facet in ${facets//,/ }; do
12847                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12848         done
12849         return 1
12850 }
12851
12852 test_129() {
12853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12854         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12855                 skip "Need MDS version with at least 2.5.56"
12856         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12857                 skip_env "ldiskfs only test"
12858         fi
12859         remote_mds_nodsh && skip "remote MDS with nodsh"
12860
12861         local ENOSPC=28
12862         local has_warning=false
12863
12864         rm -rf $DIR/$tdir
12865         mkdir -p $DIR/$tdir
12866
12867         # block size of mds1
12868         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12869         set_dir_limits $maxsize $((maxsize * 6 / 8))
12870         stack_trap "set_dir_limits 0 0"
12871         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12872         local dirsize=$(stat -c%s "$DIR/$tdir")
12873         local nfiles=0
12874         while (( $dirsize <= $maxsize )); do
12875                 $MCREATE $DIR/$tdir/file_base_$nfiles
12876                 rc=$?
12877                 # check two errors:
12878                 # ENOSPC for ext4 max_dir_size, which has been used since
12879                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12880                 if (( rc == ENOSPC )); then
12881                         set_dir_limits 0 0
12882                         echo "rc=$rc returned as expected after $nfiles files"
12883
12884                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12885                                 error "create failed w/o dir size limit"
12886
12887                         # messages may be rate limited if test is run repeatedly
12888                         check_mds_dmesg '"is approaching max"' ||
12889                                 echo "warning message should be output"
12890                         check_mds_dmesg '"has reached max"' ||
12891                                 echo "reached message should be output"
12892
12893                         dirsize=$(stat -c%s "$DIR/$tdir")
12894
12895                         [[ $dirsize -ge $maxsize ]] && return 0
12896                         error "dirsize $dirsize < $maxsize after $nfiles files"
12897                 elif (( rc != 0 )); then
12898                         break
12899                 fi
12900                 nfiles=$((nfiles + 1))
12901                 dirsize=$(stat -c%s "$DIR/$tdir")
12902         done
12903
12904         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12905 }
12906 run_test 129 "test directory size limit ========================"
12907
12908 OLDIFS="$IFS"
12909 cleanup_130() {
12910         trap 0
12911         IFS="$OLDIFS"
12912 }
12913
12914 test_130a() {
12915         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12916         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12917
12918         trap cleanup_130 EXIT RETURN
12919
12920         local fm_file=$DIR/$tfile
12921         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12922         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12923                 error "dd failed for $fm_file"
12924
12925         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12926         filefrag -ves $fm_file
12927         RC=$?
12928         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12929                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12930         [ $RC != 0 ] && error "filefrag $fm_file failed"
12931
12932         filefrag_op=$(filefrag -ve -k $fm_file |
12933                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12934         lun=$($LFS getstripe -i $fm_file)
12935
12936         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12937         IFS=$'\n'
12938         tot_len=0
12939         for line in $filefrag_op
12940         do
12941                 frag_lun=`echo $line | cut -d: -f5`
12942                 ext_len=`echo $line | cut -d: -f4`
12943                 if (( $frag_lun != $lun )); then
12944                         cleanup_130
12945                         error "FIEMAP on 1-stripe file($fm_file) failed"
12946                         return
12947                 fi
12948                 (( tot_len += ext_len ))
12949         done
12950
12951         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12952                 cleanup_130
12953                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12954                 return
12955         fi
12956
12957         cleanup_130
12958
12959         echo "FIEMAP on single striped file succeeded"
12960 }
12961 run_test 130a "FIEMAP (1-stripe file)"
12962
12963 test_130b() {
12964         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12965
12966         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12967         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12968
12969         trap cleanup_130 EXIT RETURN
12970
12971         local fm_file=$DIR/$tfile
12972         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12973                         error "setstripe on $fm_file"
12974         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12975                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12976
12977         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12978                 error "dd failed on $fm_file"
12979
12980         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12981         filefrag_op=$(filefrag -ve -k $fm_file |
12982                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12983
12984         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12985                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12986
12987         IFS=$'\n'
12988         tot_len=0
12989         num_luns=1
12990         for line in $filefrag_op
12991         do
12992                 frag_lun=$(echo $line | cut -d: -f5 |
12993                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12994                 ext_len=$(echo $line | cut -d: -f4)
12995                 if (( $frag_lun != $last_lun )); then
12996                         if (( tot_len != 1024 )); then
12997                                 cleanup_130
12998                                 error "FIEMAP on $fm_file failed; returned " \
12999                                 "len $tot_len for OST $last_lun instead of 1024"
13000                                 return
13001                         else
13002                                 (( num_luns += 1 ))
13003                                 tot_len=0
13004                         fi
13005                 fi
13006                 (( tot_len += ext_len ))
13007                 last_lun=$frag_lun
13008         done
13009         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13010                 cleanup_130
13011                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13012                         "luns or wrong len for OST $last_lun"
13013                 return
13014         fi
13015
13016         cleanup_130
13017
13018         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13019 }
13020 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13021
13022 test_130c() {
13023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13024
13025         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13026         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13027
13028         trap cleanup_130 EXIT RETURN
13029
13030         local fm_file=$DIR/$tfile
13031         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13032         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13033                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13034
13035         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13036                         error "dd failed on $fm_file"
13037
13038         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13039         filefrag_op=$(filefrag -ve -k $fm_file |
13040                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13041
13042         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13043                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13044
13045         IFS=$'\n'
13046         tot_len=0
13047         num_luns=1
13048         for line in $filefrag_op
13049         do
13050                 frag_lun=$(echo $line | cut -d: -f5 |
13051                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13052                 ext_len=$(echo $line | cut -d: -f4)
13053                 if (( $frag_lun != $last_lun )); then
13054                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13055                         if (( logical != 512 )); then
13056                                 cleanup_130
13057                                 error "FIEMAP on $fm_file failed; returned " \
13058                                 "logical start for lun $logical instead of 512"
13059                                 return
13060                         fi
13061                         if (( tot_len != 512 )); then
13062                                 cleanup_130
13063                                 error "FIEMAP on $fm_file failed; returned " \
13064                                 "len $tot_len for OST $last_lun instead of 1024"
13065                                 return
13066                         else
13067                                 (( num_luns += 1 ))
13068                                 tot_len=0
13069                         fi
13070                 fi
13071                 (( tot_len += ext_len ))
13072                 last_lun=$frag_lun
13073         done
13074         if (( num_luns != 2 || tot_len != 512 )); then
13075                 cleanup_130
13076                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13077                         "luns or wrong len for OST $last_lun"
13078                 return
13079         fi
13080
13081         cleanup_130
13082
13083         echo "FIEMAP on 2-stripe file with hole succeeded"
13084 }
13085 run_test 130c "FIEMAP (2-stripe file with hole)"
13086
13087 test_130d() {
13088         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13089
13090         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13091         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13092
13093         trap cleanup_130 EXIT RETURN
13094
13095         local fm_file=$DIR/$tfile
13096         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13097                         error "setstripe on $fm_file"
13098         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13099                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13100
13101         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13102         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13103                 error "dd failed on $fm_file"
13104
13105         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13106         filefrag_op=$(filefrag -ve -k $fm_file |
13107                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13108
13109         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13110                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13111
13112         IFS=$'\n'
13113         tot_len=0
13114         num_luns=1
13115         for line in $filefrag_op
13116         do
13117                 frag_lun=$(echo $line | cut -d: -f5 |
13118                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13119                 ext_len=$(echo $line | cut -d: -f4)
13120                 if (( $frag_lun != $last_lun )); then
13121                         if (( tot_len != 1024 )); then
13122                                 cleanup_130
13123                                 error "FIEMAP on $fm_file failed; returned " \
13124                                 "len $tot_len for OST $last_lun instead of 1024"
13125                                 return
13126                         else
13127                                 (( num_luns += 1 ))
13128                                 tot_len=0
13129                         fi
13130                 fi
13131                 (( tot_len += ext_len ))
13132                 last_lun=$frag_lun
13133         done
13134         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13135                 cleanup_130
13136                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13137                         "luns or wrong len for OST $last_lun"
13138                 return
13139         fi
13140
13141         cleanup_130
13142
13143         echo "FIEMAP on N-stripe file succeeded"
13144 }
13145 run_test 130d "FIEMAP (N-stripe file)"
13146
13147 test_130e() {
13148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13149
13150         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13151         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13152
13153         trap cleanup_130 EXIT RETURN
13154
13155         local fm_file=$DIR/$tfile
13156         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13157
13158         NUM_BLKS=512
13159         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13160         for ((i = 0; i < $NUM_BLKS; i++)); do
13161                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13162                         conv=notrunc > /dev/null 2>&1
13163         done
13164
13165         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13166         filefrag_op=$(filefrag -ve -k $fm_file |
13167                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13168
13169         last_lun=$(echo $filefrag_op | cut -d: -f5)
13170
13171         IFS=$'\n'
13172         tot_len=0
13173         num_luns=1
13174         for line in $filefrag_op; do
13175                 frag_lun=$(echo $line | cut -d: -f5)
13176                 ext_len=$(echo $line | cut -d: -f4)
13177                 if [[ "$frag_lun" != "$last_lun" ]]; then
13178                         if (( tot_len != $EXPECTED_LEN )); then
13179                                 cleanup_130
13180                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13181                         else
13182                                 (( num_luns += 1 ))
13183                                 tot_len=0
13184                         fi
13185                 fi
13186                 (( tot_len += ext_len ))
13187                 last_lun=$frag_lun
13188         done
13189         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13190                 cleanup_130
13191                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13192         fi
13193
13194         echo "FIEMAP with continuation calls succeeded"
13195 }
13196 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13197
13198 test_130f() {
13199         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13200         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13201
13202         local fm_file=$DIR/$tfile
13203         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13204                 error "multiop create with lov_delay_create on $fm_file"
13205
13206         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13207         filefrag_extents=$(filefrag -vek $fm_file |
13208                            awk '/extents? found/ { print $2 }')
13209         if [[ "$filefrag_extents" != "0" ]]; then
13210                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13211         fi
13212
13213         rm -f $fm_file
13214 }
13215 run_test 130f "FIEMAP (unstriped file)"
13216
13217 test_130g() {
13218         local file=$DIR/$tfile
13219         local nr=$((OSTCOUNT * 100))
13220
13221         $LFS setstripe -C $nr $file ||
13222                 error "failed to setstripe -C $nr $file"
13223
13224         dd if=/dev/zero of=$file count=$nr bs=1M
13225         sync
13226         nr=$($LFS getstripe -c $file)
13227
13228         local extents=$(filefrag -v $file |
13229                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13230
13231         echo "filefrag list $extents extents in file with stripecount $nr"
13232         if (( extents < nr )); then
13233                 $LFS getstripe $file
13234                 filefrag -v $file
13235                 error "filefrag printed $extents < $nr extents"
13236         fi
13237
13238         rm -f $file
13239 }
13240 run_test 130g "FIEMAP (overstripe file)"
13241
13242 # Test for writev/readv
13243 test_131a() {
13244         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13245                 error "writev test failed"
13246         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13247                 error "readv failed"
13248         rm -f $DIR/$tfile
13249 }
13250 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13251
13252 test_131b() {
13253         local fsize=$((524288 + 1048576 + 1572864))
13254         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13255                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13256                         error "append writev test failed"
13257
13258         ((fsize += 1572864 + 1048576))
13259         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13260                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13261                         error "append writev test failed"
13262         rm -f $DIR/$tfile
13263 }
13264 run_test 131b "test append writev"
13265
13266 test_131c() {
13267         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13268         error "NOT PASS"
13269 }
13270 run_test 131c "test read/write on file w/o objects"
13271
13272 test_131d() {
13273         rwv -f $DIR/$tfile -w -n 1 1572864
13274         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13275         if [ "$NOB" != 1572864 ]; then
13276                 error "Short read filed: read $NOB bytes instead of 1572864"
13277         fi
13278         rm -f $DIR/$tfile
13279 }
13280 run_test 131d "test short read"
13281
13282 test_131e() {
13283         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13284         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13285         error "read hitting hole failed"
13286         rm -f $DIR/$tfile
13287 }
13288 run_test 131e "test read hitting hole"
13289
13290 check_stats() {
13291         local facet=$1
13292         local op=$2
13293         local want=${3:-0}
13294         local res
13295
13296         case $facet in
13297         mds*) res=$(do_facet $facet \
13298                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13299                  ;;
13300         ost*) res=$(do_facet $facet \
13301                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13302                  ;;
13303         *) error "Wrong facet '$facet'" ;;
13304         esac
13305         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13306         # if the argument $3 is zero, it means any stat increment is ok.
13307         if [[ $want -gt 0 ]]; then
13308                 local count=$(echo $res | awk '{ print $2 }')
13309                 [[ $count -ne $want ]] &&
13310                         error "The $op counter on $facet is $count, not $want"
13311         fi
13312 }
13313
13314 test_133a() {
13315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13316         remote_ost_nodsh && skip "remote OST with nodsh"
13317         remote_mds_nodsh && skip "remote MDS with nodsh"
13318         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13319                 skip_env "MDS doesn't support rename stats"
13320
13321         local testdir=$DIR/${tdir}/stats_testdir
13322
13323         mkdir -p $DIR/${tdir}
13324
13325         # clear stats.
13326         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13327         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13328
13329         # verify mdt stats first.
13330         mkdir ${testdir} || error "mkdir failed"
13331         check_stats $SINGLEMDS "mkdir" 1
13332         touch ${testdir}/${tfile} || error "touch failed"
13333         check_stats $SINGLEMDS "open" 1
13334         check_stats $SINGLEMDS "close" 1
13335         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13336                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13337                 check_stats $SINGLEMDS "mknod" 2
13338         }
13339         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13340         check_stats $SINGLEMDS "unlink" 1
13341         rm -f ${testdir}/${tfile} || error "file remove failed"
13342         check_stats $SINGLEMDS "unlink" 2
13343
13344         # remove working dir and check mdt stats again.
13345         rmdir ${testdir} || error "rmdir failed"
13346         check_stats $SINGLEMDS "rmdir" 1
13347
13348         local testdir1=$DIR/${tdir}/stats_testdir1
13349         mkdir -p ${testdir}
13350         mkdir -p ${testdir1}
13351         touch ${testdir1}/test1
13352         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13353         check_stats $SINGLEMDS "crossdir_rename" 1
13354
13355         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13356         check_stats $SINGLEMDS "samedir_rename" 1
13357
13358         rm -rf $DIR/${tdir}
13359 }
13360 run_test 133a "Verifying MDT stats ========================================"
13361
13362 test_133b() {
13363         local res
13364
13365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13366         remote_ost_nodsh && skip "remote OST with nodsh"
13367         remote_mds_nodsh && skip "remote MDS with nodsh"
13368
13369         local testdir=$DIR/${tdir}/stats_testdir
13370
13371         mkdir -p ${testdir} || error "mkdir failed"
13372         touch ${testdir}/${tfile} || error "touch failed"
13373         cancel_lru_locks mdc
13374
13375         # clear stats.
13376         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13377         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13378
13379         # extra mdt stats verification.
13380         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13381         check_stats $SINGLEMDS "setattr" 1
13382         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13383         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13384         then            # LU-1740
13385                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13386                 check_stats $SINGLEMDS "getattr" 1
13387         fi
13388         rm -rf $DIR/${tdir}
13389
13390         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13391         # so the check below is not reliable
13392         [ $MDSCOUNT -eq 1 ] || return 0
13393
13394         # Sleep to avoid a cached response.
13395         #define OBD_STATFS_CACHE_SECONDS 1
13396         sleep 2
13397         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13398         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13399         $LFS df || error "lfs failed"
13400         check_stats $SINGLEMDS "statfs" 1
13401
13402         # check aggregated statfs (LU-10018)
13403         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13404                 return 0
13405         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13406                 return 0
13407         sleep 2
13408         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13409         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13410         df $DIR
13411         check_stats $SINGLEMDS "statfs" 1
13412
13413         # We want to check that the client didn't send OST_STATFS to
13414         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13415         # extra care is needed here.
13416         if remote_mds; then
13417                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13418                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13419
13420                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13421                 [ "$res" ] && error "OST got STATFS"
13422         fi
13423
13424         return 0
13425 }
13426 run_test 133b "Verifying extra MDT stats =================================="
13427
13428 test_133c() {
13429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13430         remote_ost_nodsh && skip "remote OST with nodsh"
13431         remote_mds_nodsh && skip "remote MDS with nodsh"
13432
13433         local testdir=$DIR/$tdir/stats_testdir
13434
13435         test_mkdir -p $testdir
13436
13437         # verify obdfilter stats.
13438         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13439         sync
13440         cancel_lru_locks osc
13441         wait_delete_completed
13442
13443         # clear stats.
13444         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13445         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13446
13447         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13448                 error "dd failed"
13449         sync
13450         cancel_lru_locks osc
13451         check_stats ost1 "write" 1
13452
13453         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13454         check_stats ost1 "read" 1
13455
13456         > $testdir/$tfile || error "truncate failed"
13457         check_stats ost1 "punch" 1
13458
13459         rm -f $testdir/$tfile || error "file remove failed"
13460         wait_delete_completed
13461         check_stats ost1 "destroy" 1
13462
13463         rm -rf $DIR/$tdir
13464 }
13465 run_test 133c "Verifying OST stats ========================================"
13466
13467 order_2() {
13468         local value=$1
13469         local orig=$value
13470         local order=1
13471
13472         while [ $value -ge 2 ]; do
13473                 order=$((order*2))
13474                 value=$((value/2))
13475         done
13476
13477         if [ $orig -gt $order ]; then
13478                 order=$((order*2))
13479         fi
13480         echo $order
13481 }
13482
13483 size_in_KMGT() {
13484     local value=$1
13485     local size=('K' 'M' 'G' 'T');
13486     local i=0
13487     local size_string=$value
13488
13489     while [ $value -ge 1024 ]; do
13490         if [ $i -gt 3 ]; then
13491             #T is the biggest unit we get here, if that is bigger,
13492             #just return XXXT
13493             size_string=${value}T
13494             break
13495         fi
13496         value=$((value >> 10))
13497         if [ $value -lt 1024 ]; then
13498             size_string=${value}${size[$i]}
13499             break
13500         fi
13501         i=$((i + 1))
13502     done
13503
13504     echo $size_string
13505 }
13506
13507 get_rename_size() {
13508         local size=$1
13509         local context=${2:-.}
13510         local sample=$(do_facet $SINGLEMDS $LCTL \
13511                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13512                 grep -A1 $context |
13513                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13514         echo $sample
13515 }
13516
13517 test_133d() {
13518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13519         remote_ost_nodsh && skip "remote OST with nodsh"
13520         remote_mds_nodsh && skip "remote MDS with nodsh"
13521         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13522                 skip_env "MDS doesn't support rename stats"
13523
13524         local testdir1=$DIR/${tdir}/stats_testdir1
13525         local testdir2=$DIR/${tdir}/stats_testdir2
13526         mkdir -p $DIR/${tdir}
13527
13528         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13529
13530         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13531         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13532
13533         createmany -o $testdir1/test 512 || error "createmany failed"
13534
13535         # check samedir rename size
13536         mv ${testdir1}/test0 ${testdir1}/test_0
13537
13538         local testdir1_size=$(ls -l $DIR/${tdir} |
13539                 awk '/stats_testdir1/ {print $5}')
13540         local testdir2_size=$(ls -l $DIR/${tdir} |
13541                 awk '/stats_testdir2/ {print $5}')
13542
13543         testdir1_size=$(order_2 $testdir1_size)
13544         testdir2_size=$(order_2 $testdir2_size)
13545
13546         testdir1_size=$(size_in_KMGT $testdir1_size)
13547         testdir2_size=$(size_in_KMGT $testdir2_size)
13548
13549         echo "source rename dir size: ${testdir1_size}"
13550         echo "target rename dir size: ${testdir2_size}"
13551
13552         local cmd="do_facet $SINGLEMDS $LCTL "
13553         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13554
13555         eval $cmd || error "$cmd failed"
13556         local samedir=$($cmd | grep 'same_dir')
13557         local same_sample=$(get_rename_size $testdir1_size)
13558         [ -z "$samedir" ] && error "samedir_rename_size count error"
13559         [[ $same_sample -eq 1 ]] ||
13560                 error "samedir_rename_size error $same_sample"
13561         echo "Check same dir rename stats success"
13562
13563         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13564
13565         # check crossdir rename size
13566         mv ${testdir1}/test_0 ${testdir2}/test_0
13567
13568         testdir1_size=$(ls -l $DIR/${tdir} |
13569                 awk '/stats_testdir1/ {print $5}')
13570         testdir2_size=$(ls -l $DIR/${tdir} |
13571                 awk '/stats_testdir2/ {print $5}')
13572
13573         testdir1_size=$(order_2 $testdir1_size)
13574         testdir2_size=$(order_2 $testdir2_size)
13575
13576         testdir1_size=$(size_in_KMGT $testdir1_size)
13577         testdir2_size=$(size_in_KMGT $testdir2_size)
13578
13579         echo "source rename dir size: ${testdir1_size}"
13580         echo "target rename dir size: ${testdir2_size}"
13581
13582         eval $cmd || error "$cmd failed"
13583         local crossdir=$($cmd | grep 'crossdir')
13584         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13585         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13586         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13587         [[ $src_sample -eq 1 ]] ||
13588                 error "crossdir_rename_size error $src_sample"
13589         [[ $tgt_sample -eq 1 ]] ||
13590                 error "crossdir_rename_size error $tgt_sample"
13591         echo "Check cross dir rename stats success"
13592         rm -rf $DIR/${tdir}
13593 }
13594 run_test 133d "Verifying rename_stats ========================================"
13595
13596 test_133e() {
13597         remote_mds_nodsh && skip "remote MDS with nodsh"
13598         remote_ost_nodsh && skip "remote OST with nodsh"
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600
13601         local testdir=$DIR/${tdir}/stats_testdir
13602         local ctr f0 f1 bs=32768 count=42 sum
13603
13604         mkdir -p ${testdir} || error "mkdir failed"
13605
13606         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13607
13608         for ctr in {write,read}_bytes; do
13609                 sync
13610                 cancel_lru_locks osc
13611
13612                 do_facet ost1 $LCTL set_param -n \
13613                         "obdfilter.*.exports.clear=clear"
13614
13615                 if [ $ctr = write_bytes ]; then
13616                         f0=/dev/zero
13617                         f1=${testdir}/${tfile}
13618                 else
13619                         f0=${testdir}/${tfile}
13620                         f1=/dev/null
13621                 fi
13622
13623                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13624                         error "dd failed"
13625                 sync
13626                 cancel_lru_locks osc
13627
13628                 sum=$(do_facet ost1 $LCTL get_param \
13629                         "obdfilter.*.exports.*.stats" |
13630                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13631                                 $1 == ctr { sum += $7 }
13632                                 END { printf("%0.0f", sum) }')
13633
13634                 if ((sum != bs * count)); then
13635                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13636                 fi
13637         done
13638
13639         rm -rf $DIR/${tdir}
13640 }
13641 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13642
13643 test_133f() {
13644         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13645                 skip "too old lustre for get_param -R ($facet_ver)"
13646
13647         # verifying readability.
13648         $LCTL get_param -R '*' &> /dev/null
13649
13650         # Verifing writability with badarea_io.
13651         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13652                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13653                 error "client badarea_io failed"
13654
13655         # remount the FS in case writes/reads /proc break the FS
13656         cleanup || error "failed to unmount"
13657         setup || error "failed to setup"
13658 }
13659 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13660
13661 test_133g() {
13662         remote_mds_nodsh && skip "remote MDS with nodsh"
13663         remote_ost_nodsh && skip "remote OST with nodsh"
13664
13665         local facet
13666         for facet in mds1 ost1; do
13667                 local facet_ver=$(lustre_version_code $facet)
13668                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13669                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13670                 else
13671                         log "$facet: too old lustre for get_param -R"
13672                 fi
13673                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13674                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13675                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13676                                 xargs badarea_io" ||
13677                                         error "$facet badarea_io failed"
13678                 else
13679                         skip_noexit "$facet: too old lustre for get_param -R"
13680                 fi
13681         done
13682
13683         # remount the FS in case writes/reads /proc break the FS
13684         cleanup || error "failed to unmount"
13685         setup || error "failed to setup"
13686 }
13687 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13688
13689 test_133h() {
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         remote_ost_nodsh && skip "remote OST with nodsh"
13692         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13693                 skip "Need MDS version at least 2.9.54"
13694
13695         local facet
13696         for facet in client mds1 ost1; do
13697                 # Get the list of files that are missing the terminating newline
13698                 local plist=$(do_facet $facet
13699                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13700                 local ent
13701                 for ent in $plist; do
13702                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13703                                 awk -v FS='\v' -v RS='\v\v' \
13704                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13705                                         print FILENAME}'" 2>/dev/null)
13706                         [ -z $missing ] || {
13707                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13708                                 error "file does not end with newline: $facet-$ent"
13709                         }
13710                 done
13711         done
13712 }
13713 run_test 133h "Proc files should end with newlines"
13714
13715 test_134a() {
13716         remote_mds_nodsh && skip "remote MDS with nodsh"
13717         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13718                 skip "Need MDS version at least 2.7.54"
13719
13720         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13721         cancel_lru_locks mdc
13722
13723         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13724         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13725         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13726
13727         local nr=1000
13728         createmany -o $DIR/$tdir/f $nr ||
13729                 error "failed to create $nr files in $DIR/$tdir"
13730         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13731
13732         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13733         do_facet mds1 $LCTL set_param fail_loc=0x327
13734         do_facet mds1 $LCTL set_param fail_val=500
13735         touch $DIR/$tdir/m
13736
13737         echo "sleep 10 seconds ..."
13738         sleep 10
13739         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13740
13741         do_facet mds1 $LCTL set_param fail_loc=0
13742         do_facet mds1 $LCTL set_param fail_val=0
13743         [ $lck_cnt -lt $unused ] ||
13744                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13745
13746         rm $DIR/$tdir/m
13747         unlinkmany $DIR/$tdir/f $nr
13748 }
13749 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13750
13751 test_134b() {
13752         remote_mds_nodsh && skip "remote MDS with nodsh"
13753         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13754                 skip "Need MDS version at least 2.7.54"
13755
13756         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13757         cancel_lru_locks mdc
13758
13759         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13760                         ldlm.lock_reclaim_threshold_mb)
13761         # disable reclaim temporarily
13762         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13763
13764         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13765         do_facet mds1 $LCTL set_param fail_loc=0x328
13766         do_facet mds1 $LCTL set_param fail_val=500
13767
13768         $LCTL set_param debug=+trace
13769
13770         local nr=600
13771         createmany -o $DIR/$tdir/f $nr &
13772         local create_pid=$!
13773
13774         echo "Sleep $TIMEOUT seconds ..."
13775         sleep $TIMEOUT
13776         if ! ps -p $create_pid  > /dev/null 2>&1; then
13777                 do_facet mds1 $LCTL set_param fail_loc=0
13778                 do_facet mds1 $LCTL set_param fail_val=0
13779                 do_facet mds1 $LCTL set_param \
13780                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13781                 error "createmany finished incorrectly!"
13782         fi
13783         do_facet mds1 $LCTL set_param fail_loc=0
13784         do_facet mds1 $LCTL set_param fail_val=0
13785         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13786         wait $create_pid || return 1
13787
13788         unlinkmany $DIR/$tdir/f $nr
13789 }
13790 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13791
13792 test_135() {
13793         remote_mds_nodsh && skip "remote MDS with nodsh"
13794         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13795                 skip "Need MDS version at least 2.13.50"
13796         local fname
13797
13798         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13799
13800 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13801         #set only one record at plain llog
13802         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13803
13804         #fill already existed plain llog each 64767
13805         #wrapping whole catalog
13806         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13807
13808         createmany -o $DIR/$tdir/$tfile_ 64700
13809         for (( i = 0; i < 64700; i = i + 2 ))
13810         do
13811                 rm $DIR/$tdir/$tfile_$i &
13812                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13813                 local pid=$!
13814                 wait $pid
13815         done
13816
13817         #waiting osp synchronization
13818         wait_delete_completed
13819 }
13820 run_test 135 "Race catalog processing"
13821
13822 test_136() {
13823         remote_mds_nodsh && skip "remote MDS with nodsh"
13824         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13825                 skip "Need MDS version at least 2.13.50"
13826         local fname
13827
13828         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13829         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13830         #set only one record at plain llog
13831 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13832         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13833
13834         #fill already existed 2 plain llogs each 64767
13835         #wrapping whole catalog
13836         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13837         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13838         wait_delete_completed
13839
13840         createmany -o $DIR/$tdir/$tfile_ 10
13841         sleep 25
13842
13843         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13844         for (( i = 0; i < 10; i = i + 3 ))
13845         do
13846                 rm $DIR/$tdir/$tfile_$i &
13847                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13848                 local pid=$!
13849                 wait $pid
13850                 sleep 7
13851                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13852         done
13853
13854         #waiting osp synchronization
13855         wait_delete_completed
13856 }
13857 run_test 136 "Race catalog processing 2"
13858
13859 test_140() { #bug-17379
13860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13861
13862         test_mkdir $DIR/$tdir
13863         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13864         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13865
13866         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13867         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13868         local i=0
13869         while i=$((i + 1)); do
13870                 test_mkdir $i
13871                 cd $i || error "Changing to $i"
13872                 ln -s ../stat stat || error "Creating stat symlink"
13873                 # Read the symlink until ELOOP present,
13874                 # not LBUGing the system is considered success,
13875                 # we didn't overrun the stack.
13876                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13877                 if [ $ret -ne 0 ]; then
13878                         if [ $ret -eq 40 ]; then
13879                                 break  # -ELOOP
13880                         else
13881                                 error "Open stat symlink"
13882                                         return
13883                         fi
13884                 fi
13885         done
13886         i=$((i - 1))
13887         echo "The symlink depth = $i"
13888         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13889                 error "Invalid symlink depth"
13890
13891         # Test recursive symlink
13892         ln -s symlink_self symlink_self
13893         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13894         echo "open symlink_self returns $ret"
13895         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13896 }
13897 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13898
13899 test_150a() {
13900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13901
13902         local TF="$TMP/$tfile"
13903
13904         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13905         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13906         cp $TF $DIR/$tfile
13907         cancel_lru_locks $OSC
13908         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13909         remount_client $MOUNT
13910         df -P $MOUNT
13911         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13912
13913         $TRUNCATE $TF 6000
13914         $TRUNCATE $DIR/$tfile 6000
13915         cancel_lru_locks $OSC
13916         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13917
13918         echo "12345" >>$TF
13919         echo "12345" >>$DIR/$tfile
13920         cancel_lru_locks $OSC
13921         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13922
13923         echo "12345" >>$TF
13924         echo "12345" >>$DIR/$tfile
13925         cancel_lru_locks $OSC
13926         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13927 }
13928 run_test 150a "truncate/append tests"
13929
13930 test_150b() {
13931         check_set_fallocate_or_skip
13932
13933         touch $DIR/$tfile
13934         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13935         check_fallocate $DIR/$tfile || error "fallocate failed"
13936 }
13937 run_test 150b "Verify fallocate (prealloc) functionality"
13938
13939 test_150bb() {
13940         check_set_fallocate_or_skip
13941
13942         touch $DIR/$tfile
13943         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13944         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13945         > $DIR/$tfile
13946         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13947         # precomputed md5sum for 20MB of zeroes
13948         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13949         local sum=($(md5sum $DIR/$tfile))
13950
13951         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13952
13953         check_set_fallocate 1
13954
13955         > $DIR/$tfile
13956         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13957         sum=($(md5sum $DIR/$tfile))
13958
13959         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13960 }
13961 run_test 150bb "Verify fallocate modes both zero space"
13962
13963 test_150c() {
13964         check_set_fallocate_or_skip
13965
13966         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13967         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13968         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13969         sync; sync_all_data
13970         cancel_lru_locks $OSC
13971         sleep 5
13972         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13973         want=$((OSTCOUNT * 1048576))
13974
13975         # Must allocate all requested space, not more than 5% extra
13976         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13977                 error "bytes $bytes is not $want"
13978
13979         rm -f $DIR/$tfile
13980         # verify fallocate on PFL file
13981         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13982                 error "Create $DIR/$tfile failed"
13983         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13984                         error "fallocate failed"
13985         sync; sync_all_data
13986         cancel_lru_locks $OSC
13987         sleep 5
13988         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13989         local want=$((1024 * 1048576))
13990
13991         # Must allocate all requested space, not more than 5% extra
13992         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13993                 error "bytes $bytes is not $want"
13994 }
13995 run_test 150c "Verify fallocate Size and Blocks"
13996
13997 test_150d() {
13998         check_set_fallocate_or_skip
13999
14000         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14001         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14002         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14003         sync; sync_all_data
14004         cancel_lru_locks $OSC
14005         sleep 5
14006         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14007         local want=$((OSTCOUNT * 1048576))
14008
14009         # Must allocate all requested space, not more than 5% extra
14010         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14011                 error "bytes $bytes is not $want"
14012 }
14013 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14014
14015 test_150e() {
14016         check_set_fallocate_or_skip
14017
14018         echo "df before:"
14019         $LFS df
14020         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14021         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14022                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14023
14024         # Find OST with Minimum Size
14025         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14026                        sort -un | head -1)
14027
14028         # Get 100MB per OST of the available space to reduce run time
14029         # else 60% of the available space if we are running SLOW tests
14030         if [ $SLOW == "no" ]; then
14031                 local space=$((1024 * 100 * OSTCOUNT))
14032         else
14033                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14034         fi
14035
14036         fallocate -l${space}k $DIR/$tfile ||
14037                 error "fallocate ${space}k $DIR/$tfile failed"
14038         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14039
14040         # get size immediately after fallocate. This should be correctly
14041         # updated
14042         local size=$(stat -c '%s' $DIR/$tfile)
14043         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14044
14045         # Sleep for a while for statfs to get updated. And not pull from cache.
14046         sleep 2
14047
14048         echo "df after fallocate:"
14049         $LFS df
14050
14051         (( size / 1024 == space )) || error "size $size != requested $space"
14052         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14053                 error "used $used < space $space"
14054
14055         rm $DIR/$tfile || error "rm failed"
14056         sync
14057         wait_delete_completed
14058
14059         echo "df after unlink:"
14060         $LFS df
14061 }
14062 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14063
14064 test_150f() {
14065         local size
14066         local blocks
14067         local want_size_before=20480 # in bytes
14068         local want_blocks_before=40 # 512 sized blocks
14069         local want_blocks_after=24  # 512 sized blocks
14070         local length=$(((want_blocks_before - want_blocks_after) * 512))
14071
14072         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14073                 skip "need at least 2.14.0 for fallocate punch"
14074
14075         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14076                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14077         fi
14078
14079         check_set_fallocate_or_skip
14080         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14081
14082         echo "Verify fallocate punch: Range within the file range"
14083         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14084                 error "dd failed for bs 4096 and count 5"
14085
14086         # Call fallocate with punch range which is within the file range
14087         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14088                 error "fallocate failed: offset 4096 and length $length"
14089         # client must see changes immediately after fallocate
14090         size=$(stat -c '%s' $DIR/$tfile)
14091         blocks=$(stat -c '%b' $DIR/$tfile)
14092
14093         # Verify punch worked.
14094         (( blocks == want_blocks_after )) ||
14095                 error "punch failed: blocks $blocks != $want_blocks_after"
14096
14097         (( size == want_size_before )) ||
14098                 error "punch failed: size $size != $want_size_before"
14099
14100         # Verify there is hole in file
14101         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14102         # precomputed md5sum
14103         local expect="4a9a834a2db02452929c0a348273b4aa"
14104
14105         cksum=($(md5sum $DIR/$tfile))
14106         [[ "${cksum[0]}" == "$expect" ]] ||
14107                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14108
14109         # Start second sub-case for fallocate punch.
14110         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14111         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14112                 error "dd failed for bs 4096 and count 5"
14113
14114         # Punch range less than block size will have no change in block count
14115         want_blocks_after=40  # 512 sized blocks
14116
14117         # Punch overlaps two blocks and less than blocksize
14118         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14119                 error "fallocate failed: offset 4000 length 3000"
14120         size=$(stat -c '%s' $DIR/$tfile)
14121         blocks=$(stat -c '%b' $DIR/$tfile)
14122
14123         # Verify punch worked.
14124         (( blocks == want_blocks_after )) ||
14125                 error "punch failed: blocks $blocks != $want_blocks_after"
14126
14127         (( size == want_size_before )) ||
14128                 error "punch failed: size $size != $want_size_before"
14129
14130         # Verify if range is really zero'ed out. We expect Zeros.
14131         # precomputed md5sum
14132         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14133         cksum=($(md5sum $DIR/$tfile))
14134         [[ "${cksum[0]}" == "$expect" ]] ||
14135                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14136 }
14137 run_test 150f "Verify fallocate punch functionality"
14138
14139 test_150g() {
14140         local space
14141         local size
14142         local blocks
14143         local blocks_after
14144         local size_after
14145         local BS=4096 # Block size in bytes
14146
14147         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14148                 skip "need at least 2.14.0 for fallocate punch"
14149
14150         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14151                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14152         fi
14153
14154         check_set_fallocate_or_skip
14155         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14156
14157         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14158                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14159
14160         # Get 100MB per OST of the available space to reduce run time
14161         # else 60% of the available space if we are running SLOW tests
14162         if [ $SLOW == "no" ]; then
14163                 space=$((1024 * 100 * OSTCOUNT))
14164         else
14165                 # Find OST with Minimum Size
14166                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14167                         sort -un | head -1)
14168                 echo "min size OST: $space"
14169                 space=$(((space * 60)/100 * OSTCOUNT))
14170         fi
14171         # space in 1k units, round to 4k blocks
14172         local blkcount=$((space * 1024 / $BS))
14173
14174         echo "Verify fallocate punch: Very large Range"
14175         fallocate -l${space}k $DIR/$tfile ||
14176                 error "fallocate ${space}k $DIR/$tfile failed"
14177         # write 1M at the end, start and in the middle
14178         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14179                 error "dd failed: bs $BS count 256"
14180         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14181                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14182         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14183                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14184
14185         # Gather stats.
14186         size=$(stat -c '%s' $DIR/$tfile)
14187
14188         # gather punch length.
14189         local punch_size=$((size - (BS * 2)))
14190
14191         echo "punch_size = $punch_size"
14192         echo "size - punch_size: $((size - punch_size))"
14193         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14194
14195         # Call fallocate to punch all except 2 blocks. We leave the
14196         # first and the last block
14197         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14198         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14199                 error "fallocate failed: offset $BS length $punch_size"
14200
14201         size_after=$(stat -c '%s' $DIR/$tfile)
14202         blocks_after=$(stat -c '%b' $DIR/$tfile)
14203
14204         # Verify punch worked.
14205         # Size should be kept
14206         (( size == size_after )) ||
14207                 error "punch failed: size $size != $size_after"
14208
14209         # two 4k data blocks to remain plus possible 1 extra extent block
14210         (( blocks_after <= ((BS / 512) * 3) )) ||
14211                 error "too many blocks remains: $blocks_after"
14212
14213         # Verify that file has hole between the first and the last blocks
14214         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14215         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14216
14217         echo "Hole at [$hole_start, $hole_end)"
14218         (( hole_start == BS )) ||
14219                 error "no hole at offset $BS after punch"
14220
14221         (( hole_end == BS + punch_size )) ||
14222                 error "data at offset $hole_end < $((BS + punch_size))"
14223 }
14224 run_test 150g "Verify fallocate punch on large range"
14225
14226 #LU-2902 roc_hit was not able to read all values from lproc
14227 function roc_hit_init() {
14228         local list=$(comma_list $(osts_nodes))
14229         local dir=$DIR/$tdir-check
14230         local file=$dir/$tfile
14231         local BEFORE
14232         local AFTER
14233         local idx
14234
14235         test_mkdir $dir
14236         #use setstripe to do a write to every ost
14237         for i in $(seq 0 $((OSTCOUNT-1))); do
14238                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14239                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14240                 idx=$(printf %04x $i)
14241                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14242                         awk '$1 == "cache_access" {sum += $7}
14243                                 END { printf("%0.0f", sum) }')
14244
14245                 cancel_lru_locks osc
14246                 cat $file >/dev/null
14247
14248                 AFTER=$(get_osd_param $list *OST*$idx stats |
14249                         awk '$1 == "cache_access" {sum += $7}
14250                                 END { printf("%0.0f", sum) }')
14251
14252                 echo BEFORE:$BEFORE AFTER:$AFTER
14253                 if ! let "AFTER - BEFORE == 4"; then
14254                         rm -rf $dir
14255                         error "roc_hit is not safe to use"
14256                 fi
14257                 rm $file
14258         done
14259
14260         rm -rf $dir
14261 }
14262
14263 function roc_hit() {
14264         local list=$(comma_list $(osts_nodes))
14265         echo $(get_osd_param $list '' stats |
14266                 awk '$1 == "cache_hit" {sum += $7}
14267                         END { printf("%0.0f", sum) }')
14268 }
14269
14270 function set_cache() {
14271         local on=1
14272
14273         if [ "$2" == "off" ]; then
14274                 on=0;
14275         fi
14276         local list=$(comma_list $(osts_nodes))
14277         set_osd_param $list '' $1_cache_enable $on
14278
14279         cancel_lru_locks osc
14280 }
14281
14282 test_151() {
14283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14284         remote_ost_nodsh && skip "remote OST with nodsh"
14285
14286         local CPAGES=3
14287         local list=$(comma_list $(osts_nodes))
14288
14289         # check whether obdfilter is cache capable at all
14290         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14291                 skip "not cache-capable obdfilter"
14292         fi
14293
14294         # check cache is enabled on all obdfilters
14295         if get_osd_param $list '' read_cache_enable | grep 0; then
14296                 skip "oss cache is disabled"
14297         fi
14298
14299         set_osd_param $list '' writethrough_cache_enable 1
14300
14301         # check write cache is enabled on all obdfilters
14302         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14303                 skip "oss write cache is NOT enabled"
14304         fi
14305
14306         roc_hit_init
14307
14308         #define OBD_FAIL_OBD_NO_LRU  0x609
14309         do_nodes $list $LCTL set_param fail_loc=0x609
14310
14311         # pages should be in the case right after write
14312         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14313                 error "dd failed"
14314
14315         local BEFORE=$(roc_hit)
14316         cancel_lru_locks osc
14317         cat $DIR/$tfile >/dev/null
14318         local AFTER=$(roc_hit)
14319
14320         do_nodes $list $LCTL set_param fail_loc=0
14321
14322         if ! let "AFTER - BEFORE == CPAGES"; then
14323                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14324         fi
14325
14326         cancel_lru_locks osc
14327         # invalidates OST cache
14328         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14329         set_osd_param $list '' read_cache_enable 0
14330         cat $DIR/$tfile >/dev/null
14331
14332         # now data shouldn't be found in the cache
14333         BEFORE=$(roc_hit)
14334         cancel_lru_locks osc
14335         cat $DIR/$tfile >/dev/null
14336         AFTER=$(roc_hit)
14337         if let "AFTER - BEFORE != 0"; then
14338                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14339         fi
14340
14341         set_osd_param $list '' read_cache_enable 1
14342         rm -f $DIR/$tfile
14343 }
14344 run_test 151 "test cache on oss and controls ==============================="
14345
14346 test_152() {
14347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14348
14349         local TF="$TMP/$tfile"
14350
14351         # simulate ENOMEM during write
14352 #define OBD_FAIL_OST_NOMEM      0x226
14353         lctl set_param fail_loc=0x80000226
14354         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14355         cp $TF $DIR/$tfile
14356         sync || error "sync failed"
14357         lctl set_param fail_loc=0
14358
14359         # discard client's cache
14360         cancel_lru_locks osc
14361
14362         # simulate ENOMEM during read
14363         lctl set_param fail_loc=0x80000226
14364         cmp $TF $DIR/$tfile || error "cmp failed"
14365         lctl set_param fail_loc=0
14366
14367         rm -f $TF
14368 }
14369 run_test 152 "test read/write with enomem ============================"
14370
14371 test_153() {
14372         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14373 }
14374 run_test 153 "test if fdatasync does not crash ======================="
14375
14376 dot_lustre_fid_permission_check() {
14377         local fid=$1
14378         local ffid=$MOUNT/.lustre/fid/$fid
14379         local test_dir=$2
14380
14381         echo "stat fid $fid"
14382         stat $ffid > /dev/null || error "stat $ffid failed."
14383         echo "touch fid $fid"
14384         touch $ffid || error "touch $ffid failed."
14385         echo "write to fid $fid"
14386         cat /etc/hosts > $ffid || error "write $ffid failed."
14387         echo "read fid $fid"
14388         diff /etc/hosts $ffid || error "read $ffid failed."
14389         echo "append write to fid $fid"
14390         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14391         echo "rename fid $fid"
14392         mv $ffid $test_dir/$tfile.1 &&
14393                 error "rename $ffid to $tfile.1 should fail."
14394         touch $test_dir/$tfile.1
14395         mv $test_dir/$tfile.1 $ffid &&
14396                 error "rename $tfile.1 to $ffid should fail."
14397         rm -f $test_dir/$tfile.1
14398         echo "truncate fid $fid"
14399         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14400         echo "link fid $fid"
14401         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14402         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14403                 echo "setfacl fid $fid"
14404                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14405                 echo "getfacl fid $fid"
14406                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14407         fi
14408         echo "unlink fid $fid"
14409         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14410         echo "mknod fid $fid"
14411         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14412
14413         fid=[0xf00000400:0x1:0x0]
14414         ffid=$MOUNT/.lustre/fid/$fid
14415
14416         echo "stat non-exist fid $fid"
14417         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14418         echo "write to non-exist fid $fid"
14419         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14420         echo "link new fid $fid"
14421         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14422
14423         mkdir -p $test_dir/$tdir
14424         touch $test_dir/$tdir/$tfile
14425         fid=$($LFS path2fid $test_dir/$tdir)
14426         rc=$?
14427         [ $rc -ne 0 ] &&
14428                 error "error: could not get fid for $test_dir/$dir/$tfile."
14429
14430         ffid=$MOUNT/.lustre/fid/$fid
14431
14432         echo "ls $fid"
14433         ls $ffid > /dev/null || error "ls $ffid failed."
14434         echo "touch $fid/$tfile.1"
14435         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14436
14437         echo "touch $MOUNT/.lustre/fid/$tfile"
14438         touch $MOUNT/.lustre/fid/$tfile && \
14439                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14440
14441         echo "setxattr to $MOUNT/.lustre/fid"
14442         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14443
14444         echo "listxattr for $MOUNT/.lustre/fid"
14445         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14446
14447         echo "delxattr from $MOUNT/.lustre/fid"
14448         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14449
14450         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14451         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14452                 error "touch invalid fid should fail."
14453
14454         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14455         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14456                 error "touch non-normal fid should fail."
14457
14458         echo "rename $tdir to $MOUNT/.lustre/fid"
14459         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14460                 error "rename to $MOUNT/.lustre/fid should fail."
14461
14462         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14463         then            # LU-3547
14464                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14465                 local new_obf_mode=777
14466
14467                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14468                 chmod $new_obf_mode $DIR/.lustre/fid ||
14469                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14470
14471                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14472                 [ $obf_mode -eq $new_obf_mode ] ||
14473                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14474
14475                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14476                 chmod $old_obf_mode $DIR/.lustre/fid ||
14477                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14478         fi
14479
14480         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14481         fid=$($LFS path2fid $test_dir/$tfile-2)
14482
14483         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14484         then # LU-5424
14485                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14486                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14487                         error "create lov data thru .lustre failed"
14488         fi
14489         echo "cp /etc/passwd $test_dir/$tfile-2"
14490         cp /etc/passwd $test_dir/$tfile-2 ||
14491                 error "copy to $test_dir/$tfile-2 failed."
14492         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14493         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14494                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14495
14496         rm -rf $test_dir/tfile.lnk
14497         rm -rf $test_dir/$tfile-2
14498 }
14499
14500 test_154A() {
14501         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14502                 skip "Need MDS version at least 2.4.1"
14503
14504         local tf=$DIR/$tfile
14505         touch $tf
14506
14507         local fid=$($LFS path2fid $tf)
14508         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14509
14510         # check that we get the same pathname back
14511         local rootpath
14512         local found
14513         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14514                 echo "$rootpath $fid"
14515                 found=$($LFS fid2path $rootpath "$fid")
14516                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14517                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14518         done
14519
14520         # check wrong root path format
14521         rootpath=$MOUNT"_wrong"
14522         found=$($LFS fid2path $rootpath "$fid")
14523         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14524 }
14525 run_test 154A "lfs path2fid and fid2path basic checks"
14526
14527 test_154B() {
14528         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14529                 skip "Need MDS version at least 2.4.1"
14530
14531         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14532         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14533         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14534         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14535
14536         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14537         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14538
14539         # check that we get the same pathname
14540         echo "PFID: $PFID, name: $name"
14541         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14542         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14543         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14544                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14545
14546         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14547 }
14548 run_test 154B "verify the ll_decode_linkea tool"
14549
14550 test_154a() {
14551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14552         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14553         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14554                 skip "Need MDS version at least 2.2.51"
14555         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14556
14557         cp /etc/hosts $DIR/$tfile
14558
14559         fid=$($LFS path2fid $DIR/$tfile)
14560         rc=$?
14561         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14562
14563         dot_lustre_fid_permission_check "$fid" $DIR ||
14564                 error "dot lustre permission check $fid failed"
14565
14566         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14567
14568         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14569
14570         touch $MOUNT/.lustre/file &&
14571                 error "creation is not allowed under .lustre"
14572
14573         mkdir $MOUNT/.lustre/dir &&
14574                 error "mkdir is not allowed under .lustre"
14575
14576         rm -rf $DIR/$tfile
14577 }
14578 run_test 154a "Open-by-FID"
14579
14580 test_154b() {
14581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14582         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14584         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14585                 skip "Need MDS version at least 2.2.51"
14586
14587         local remote_dir=$DIR/$tdir/remote_dir
14588         local MDTIDX=1
14589         local rc=0
14590
14591         mkdir -p $DIR/$tdir
14592         $LFS mkdir -i $MDTIDX $remote_dir ||
14593                 error "create remote directory failed"
14594
14595         cp /etc/hosts $remote_dir/$tfile
14596
14597         fid=$($LFS path2fid $remote_dir/$tfile)
14598         rc=$?
14599         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14600
14601         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14602                 error "dot lustre permission check $fid failed"
14603         rm -rf $DIR/$tdir
14604 }
14605 run_test 154b "Open-by-FID for remote directory"
14606
14607 test_154c() {
14608         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14609                 skip "Need MDS version at least 2.4.1"
14610
14611         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14612         local FID1=$($LFS path2fid $DIR/$tfile.1)
14613         local FID2=$($LFS path2fid $DIR/$tfile.2)
14614         local FID3=$($LFS path2fid $DIR/$tfile.3)
14615
14616         local N=1
14617         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14618                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14619                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14620                 local want=FID$N
14621                 [ "$FID" = "${!want}" ] ||
14622                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14623                 N=$((N + 1))
14624         done
14625
14626         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14627         do
14628                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14629                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14630                 N=$((N + 1))
14631         done
14632 }
14633 run_test 154c "lfs path2fid and fid2path multiple arguments"
14634
14635 test_154d() {
14636         remote_mds_nodsh && skip "remote MDS with nodsh"
14637         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14638                 skip "Need MDS version at least 2.5.53"
14639
14640         if remote_mds; then
14641                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14642         else
14643                 nid="0@lo"
14644         fi
14645         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14646         local fd
14647         local cmd
14648
14649         rm -f $DIR/$tfile
14650         touch $DIR/$tfile
14651
14652         local fid=$($LFS path2fid $DIR/$tfile)
14653         # Open the file
14654         fd=$(free_fd)
14655         cmd="exec $fd<$DIR/$tfile"
14656         eval $cmd
14657         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14658         echo "$fid_list" | grep "$fid"
14659         rc=$?
14660
14661         cmd="exec $fd>/dev/null"
14662         eval $cmd
14663         if [ $rc -ne 0 ]; then
14664                 error "FID $fid not found in open files list $fid_list"
14665         fi
14666 }
14667 run_test 154d "Verify open file fid"
14668
14669 test_154e()
14670 {
14671         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14672                 skip "Need MDS version at least 2.6.50"
14673
14674         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14675                 error ".lustre returned by readdir"
14676         fi
14677 }
14678 run_test 154e ".lustre is not returned by readdir"
14679
14680 test_154f() {
14681         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14682
14683         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14684         test_mkdir -p -c1 $DIR/$tdir/d
14685         # test dirs inherit from its stripe
14686         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14687         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14688         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14689         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14690         touch $DIR/f
14691
14692         # get fid of parents
14693         local FID0=$($LFS path2fid $DIR/$tdir/d)
14694         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14695         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14696         local FID3=$($LFS path2fid $DIR)
14697
14698         # check that path2fid --parents returns expected <parent_fid>/name
14699         # 1) test for a directory (single parent)
14700         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14701         [ "$parent" == "$FID0/foo1" ] ||
14702                 error "expected parent: $FID0/foo1, got: $parent"
14703
14704         # 2) test for a file with nlink > 1 (multiple parents)
14705         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14706         echo "$parent" | grep -F "$FID1/$tfile" ||
14707                 error "$FID1/$tfile not returned in parent list"
14708         echo "$parent" | grep -F "$FID2/link" ||
14709                 error "$FID2/link not returned in parent list"
14710
14711         # 3) get parent by fid
14712         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14713         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14714         echo "$parent" | grep -F "$FID1/$tfile" ||
14715                 error "$FID1/$tfile not returned in parent list (by fid)"
14716         echo "$parent" | grep -F "$FID2/link" ||
14717                 error "$FID2/link not returned in parent list (by fid)"
14718
14719         # 4) test for entry in root directory
14720         parent=$($LFS path2fid --parents $DIR/f)
14721         echo "$parent" | grep -F "$FID3/f" ||
14722                 error "$FID3/f not returned in parent list"
14723
14724         # 5) test it on root directory
14725         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14726                 error "$MOUNT should not have parents"
14727
14728         # enable xattr caching and check that linkea is correctly updated
14729         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14730         save_lustre_params client "llite.*.xattr_cache" > $save
14731         lctl set_param llite.*.xattr_cache 1
14732
14733         # 6.1) linkea update on rename
14734         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14735
14736         # get parents by fid
14737         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14738         # foo1 should no longer be returned in parent list
14739         echo "$parent" | grep -F "$FID1" &&
14740                 error "$FID1 should no longer be in parent list"
14741         # the new path should appear
14742         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14743                 error "$FID2/$tfile.moved is not in parent list"
14744
14745         # 6.2) linkea update on unlink
14746         rm -f $DIR/$tdir/d/foo2/link
14747         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14748         # foo2/link should no longer be returned in parent list
14749         echo "$parent" | grep -F "$FID2/link" &&
14750                 error "$FID2/link should no longer be in parent list"
14751         true
14752
14753         rm -f $DIR/f
14754         restore_lustre_params < $save
14755         rm -f $save
14756 }
14757 run_test 154f "get parent fids by reading link ea"
14758
14759 test_154g()
14760 {
14761         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14762         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14763            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14764                 skip "Need MDS version at least 2.6.92"
14765
14766         mkdir -p $DIR/$tdir
14767         llapi_fid_test -d $DIR/$tdir
14768 }
14769 run_test 154g "various llapi FID tests"
14770
14771 test_155_small_load() {
14772     local temp=$TMP/$tfile
14773     local file=$DIR/$tfile
14774
14775     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14776         error "dd of=$temp bs=6096 count=1 failed"
14777     cp $temp $file
14778     cancel_lru_locks $OSC
14779     cmp $temp $file || error "$temp $file differ"
14780
14781     $TRUNCATE $temp 6000
14782     $TRUNCATE $file 6000
14783     cmp $temp $file || error "$temp $file differ (truncate1)"
14784
14785     echo "12345" >>$temp
14786     echo "12345" >>$file
14787     cmp $temp $file || error "$temp $file differ (append1)"
14788
14789     echo "12345" >>$temp
14790     echo "12345" >>$file
14791     cmp $temp $file || error "$temp $file differ (append2)"
14792
14793     rm -f $temp $file
14794     true
14795 }
14796
14797 test_155_big_load() {
14798         remote_ost_nodsh && skip "remote OST with nodsh"
14799
14800         local temp=$TMP/$tfile
14801         local file=$DIR/$tfile
14802
14803         free_min_max
14804         local cache_size=$(do_facet ost$((MAXI+1)) \
14805                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14806         local large_file_size=$((cache_size * 2))
14807
14808         echo "OSS cache size: $cache_size KB"
14809         echo "Large file size: $large_file_size KB"
14810
14811         [ $MAXV -le $large_file_size ] &&
14812                 skip_env "max available OST size needs > $large_file_size KB"
14813
14814         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14815
14816         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14817                 error "dd of=$temp bs=$large_file_size count=1k failed"
14818         cp $temp $file
14819         ls -lh $temp $file
14820         cancel_lru_locks osc
14821         cmp $temp $file || error "$temp $file differ"
14822
14823         rm -f $temp $file
14824         true
14825 }
14826
14827 save_writethrough() {
14828         local facets=$(get_facets OST)
14829
14830         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14831 }
14832
14833 test_155a() {
14834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14835
14836         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14837
14838         save_writethrough $p
14839
14840         set_cache read on
14841         set_cache writethrough on
14842         test_155_small_load
14843         restore_lustre_params < $p
14844         rm -f $p
14845 }
14846 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14847
14848 test_155b() {
14849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14850
14851         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14852
14853         save_writethrough $p
14854
14855         set_cache read on
14856         set_cache writethrough off
14857         test_155_small_load
14858         restore_lustre_params < $p
14859         rm -f $p
14860 }
14861 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14862
14863 test_155c() {
14864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14865
14866         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14867
14868         save_writethrough $p
14869
14870         set_cache read off
14871         set_cache writethrough on
14872         test_155_small_load
14873         restore_lustre_params < $p
14874         rm -f $p
14875 }
14876 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14877
14878 test_155d() {
14879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14880
14881         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14882
14883         save_writethrough $p
14884
14885         set_cache read off
14886         set_cache writethrough off
14887         test_155_small_load
14888         restore_lustre_params < $p
14889         rm -f $p
14890 }
14891 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14892
14893 test_155e() {
14894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14895
14896         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14897
14898         save_writethrough $p
14899
14900         set_cache read on
14901         set_cache writethrough on
14902         test_155_big_load
14903         restore_lustre_params < $p
14904         rm -f $p
14905 }
14906 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14907
14908 test_155f() {
14909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14910
14911         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14912
14913         save_writethrough $p
14914
14915         set_cache read on
14916         set_cache writethrough off
14917         test_155_big_load
14918         restore_lustre_params < $p
14919         rm -f $p
14920 }
14921 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14922
14923 test_155g() {
14924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14925
14926         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14927
14928         save_writethrough $p
14929
14930         set_cache read off
14931         set_cache writethrough on
14932         test_155_big_load
14933         restore_lustre_params < $p
14934         rm -f $p
14935 }
14936 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14937
14938 test_155h() {
14939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14940
14941         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14942
14943         save_writethrough $p
14944
14945         set_cache read off
14946         set_cache writethrough off
14947         test_155_big_load
14948         restore_lustre_params < $p
14949         rm -f $p
14950 }
14951 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14952
14953 test_156() {
14954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14955         remote_ost_nodsh && skip "remote OST with nodsh"
14956         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14957                 skip "stats not implemented on old servers"
14958         [ "$ost1_FSTYPE" = "zfs" ] &&
14959                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14960
14961         local CPAGES=3
14962         local BEFORE
14963         local AFTER
14964         local file="$DIR/$tfile"
14965         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14966
14967         save_writethrough $p
14968         roc_hit_init
14969
14970         log "Turn on read and write cache"
14971         set_cache read on
14972         set_cache writethrough on
14973
14974         log "Write data and read it back."
14975         log "Read should be satisfied from the cache."
14976         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14977         BEFORE=$(roc_hit)
14978         cancel_lru_locks osc
14979         cat $file >/dev/null
14980         AFTER=$(roc_hit)
14981         if ! let "AFTER - BEFORE == CPAGES"; then
14982                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14983         else
14984                 log "cache hits: before: $BEFORE, after: $AFTER"
14985         fi
14986
14987         log "Read again; it should be satisfied from the cache."
14988         BEFORE=$AFTER
14989         cancel_lru_locks osc
14990         cat $file >/dev/null
14991         AFTER=$(roc_hit)
14992         if ! let "AFTER - BEFORE == CPAGES"; then
14993                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14994         else
14995                 log "cache hits:: before: $BEFORE, after: $AFTER"
14996         fi
14997
14998         log "Turn off the read cache and turn on the write cache"
14999         set_cache read off
15000         set_cache writethrough on
15001
15002         log "Read again; it should be satisfied from the cache."
15003         BEFORE=$(roc_hit)
15004         cancel_lru_locks osc
15005         cat $file >/dev/null
15006         AFTER=$(roc_hit)
15007         if ! let "AFTER - BEFORE == CPAGES"; then
15008                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15009         else
15010                 log "cache hits:: before: $BEFORE, after: $AFTER"
15011         fi
15012
15013         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15014                 # > 2.12.56 uses pagecache if cached
15015                 log "Read again; it should not be satisfied from the cache."
15016                 BEFORE=$AFTER
15017                 cancel_lru_locks osc
15018                 cat $file >/dev/null
15019                 AFTER=$(roc_hit)
15020                 if ! let "AFTER - BEFORE == 0"; then
15021                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15022                 else
15023                         log "cache hits:: before: $BEFORE, after: $AFTER"
15024                 fi
15025         fi
15026
15027         log "Write data and read it back."
15028         log "Read should be satisfied from the cache."
15029         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15030         BEFORE=$(roc_hit)
15031         cancel_lru_locks osc
15032         cat $file >/dev/null
15033         AFTER=$(roc_hit)
15034         if ! let "AFTER - BEFORE == CPAGES"; then
15035                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15036         else
15037                 log "cache hits:: before: $BEFORE, after: $AFTER"
15038         fi
15039
15040         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15041                 # > 2.12.56 uses pagecache if cached
15042                 log "Read again; it should not be satisfied from the cache."
15043                 BEFORE=$AFTER
15044                 cancel_lru_locks osc
15045                 cat $file >/dev/null
15046                 AFTER=$(roc_hit)
15047                 if ! let "AFTER - BEFORE == 0"; then
15048                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15049                 else
15050                         log "cache hits:: before: $BEFORE, after: $AFTER"
15051                 fi
15052         fi
15053
15054         log "Turn off read and write cache"
15055         set_cache read off
15056         set_cache writethrough off
15057
15058         log "Write data and read it back"
15059         log "It should not be satisfied from the cache."
15060         rm -f $file
15061         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15062         cancel_lru_locks osc
15063         BEFORE=$(roc_hit)
15064         cat $file >/dev/null
15065         AFTER=$(roc_hit)
15066         if ! let "AFTER - BEFORE == 0"; then
15067                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15068         else
15069                 log "cache hits:: before: $BEFORE, after: $AFTER"
15070         fi
15071
15072         log "Turn on the read cache and turn off the write cache"
15073         set_cache read on
15074         set_cache writethrough off
15075
15076         log "Write data and read it back"
15077         log "It should not be satisfied from the cache."
15078         rm -f $file
15079         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15080         BEFORE=$(roc_hit)
15081         cancel_lru_locks osc
15082         cat $file >/dev/null
15083         AFTER=$(roc_hit)
15084         if ! let "AFTER - BEFORE == 0"; then
15085                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15086         else
15087                 log "cache hits:: before: $BEFORE, after: $AFTER"
15088         fi
15089
15090         log "Read again; it should be satisfied from the cache."
15091         BEFORE=$(roc_hit)
15092         cancel_lru_locks osc
15093         cat $file >/dev/null
15094         AFTER=$(roc_hit)
15095         if ! let "AFTER - BEFORE == CPAGES"; then
15096                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15097         else
15098                 log "cache hits:: before: $BEFORE, after: $AFTER"
15099         fi
15100
15101         restore_lustre_params < $p
15102         rm -f $p $file
15103 }
15104 run_test 156 "Verification of tunables"
15105
15106 test_160a() {
15107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15108         remote_mds_nodsh && skip "remote MDS with nodsh"
15109         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15110                 skip "Need MDS version at least 2.2.0"
15111
15112         changelog_register || error "changelog_register failed"
15113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15114         changelog_users $SINGLEMDS | grep -q $cl_user ||
15115                 error "User $cl_user not found in changelog_users"
15116
15117         # change something
15118         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15119         changelog_clear 0 || error "changelog_clear failed"
15120         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15121         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15122         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15123         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15124         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15125         rm $DIR/$tdir/pics/desktop.jpg
15126
15127         changelog_dump | tail -10
15128
15129         echo "verifying changelog mask"
15130         changelog_chmask "-MKDIR"
15131         changelog_chmask "-CLOSE"
15132
15133         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15134         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15135
15136         changelog_chmask "+MKDIR"
15137         changelog_chmask "+CLOSE"
15138
15139         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15140         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15141
15142         changelog_dump | tail -10
15143         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15144         CLOSES=$(changelog_dump | grep -c "CLOSE")
15145         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15146         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15147
15148         # verify contents
15149         echo "verifying target fid"
15150         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15151         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15152         [ "$fidc" == "$fidf" ] ||
15153                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15154         echo "verifying parent fid"
15155         # The FID returned from the Changelog may be the directory shard on
15156         # a different MDT, and not the FID returned by path2fid on the parent.
15157         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15158         # since this is what will matter when recreating this file in the tree.
15159         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15160         local pathp=$($LFS fid2path $MOUNT "$fidp")
15161         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15162                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15163
15164         echo "getting records for $cl_user"
15165         changelog_users $SINGLEMDS
15166         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15167         local nclr=3
15168         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15169                 error "changelog_clear failed"
15170         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15171         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15172         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15173                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15174
15175         local min0_rec=$(changelog_users $SINGLEMDS |
15176                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15177         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15178                           awk '{ print $1; exit; }')
15179
15180         changelog_dump | tail -n 5
15181         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15182         [ $first_rec == $((min0_rec + 1)) ] ||
15183                 error "first index should be $min0_rec + 1 not $first_rec"
15184
15185         # LU-3446 changelog index reset on MDT restart
15186         local cur_rec1=$(changelog_users $SINGLEMDS |
15187                          awk '/^current.index:/ { print $NF }')
15188         changelog_clear 0 ||
15189                 error "clear all changelog records for $cl_user failed"
15190         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15191         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15192                 error "Fail to start $SINGLEMDS"
15193         local cur_rec2=$(changelog_users $SINGLEMDS |
15194                          awk '/^current.index:/ { print $NF }')
15195         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15196         [ $cur_rec1 == $cur_rec2 ] ||
15197                 error "current index should be $cur_rec1 not $cur_rec2"
15198
15199         echo "verifying users from this test are deregistered"
15200         changelog_deregister || error "changelog_deregister failed"
15201         changelog_users $SINGLEMDS | grep -q $cl_user &&
15202                 error "User '$cl_user' still in changelog_users"
15203
15204         # lctl get_param -n mdd.*.changelog_users
15205         # current index: 144
15206         # ID    index (idle seconds)
15207         # cl3   144 (2)
15208         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15209                 # this is the normal case where all users were deregistered
15210                 # make sure no new records are added when no users are present
15211                 local last_rec1=$(changelog_users $SINGLEMDS |
15212                                   awk '/^current.index:/ { print $NF }')
15213                 touch $DIR/$tdir/chloe
15214                 local last_rec2=$(changelog_users $SINGLEMDS |
15215                                   awk '/^current.index:/ { print $NF }')
15216                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15217                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15218         else
15219                 # any changelog users must be leftovers from a previous test
15220                 changelog_users $SINGLEMDS
15221                 echo "other changelog users; can't verify off"
15222         fi
15223 }
15224 run_test 160a "changelog sanity"
15225
15226 test_160b() { # LU-3587
15227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15228         remote_mds_nodsh && skip "remote MDS with nodsh"
15229         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15230                 skip "Need MDS version at least 2.2.0"
15231
15232         changelog_register || error "changelog_register failed"
15233         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15234         changelog_users $SINGLEMDS | grep -q $cl_user ||
15235                 error "User '$cl_user' not found in changelog_users"
15236
15237         local longname1=$(str_repeat a 255)
15238         local longname2=$(str_repeat b 255)
15239
15240         cd $DIR
15241         echo "creating very long named file"
15242         touch $longname1 || error "create of '$longname1' failed"
15243         echo "renaming very long named file"
15244         mv $longname1 $longname2
15245
15246         changelog_dump | grep RENME | tail -n 5
15247         rm -f $longname2
15248 }
15249 run_test 160b "Verify that very long rename doesn't crash in changelog"
15250
15251 test_160c() {
15252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15253         remote_mds_nodsh && skip "remote MDS with nodsh"
15254
15255         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15256                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15257                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15258                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15259
15260         local rc=0
15261
15262         # Registration step
15263         changelog_register || error "changelog_register failed"
15264
15265         rm -rf $DIR/$tdir
15266         mkdir -p $DIR/$tdir
15267         $MCREATE $DIR/$tdir/foo_160c
15268         changelog_chmask "-TRUNC"
15269         $TRUNCATE $DIR/$tdir/foo_160c 200
15270         changelog_chmask "+TRUNC"
15271         $TRUNCATE $DIR/$tdir/foo_160c 199
15272         changelog_dump | tail -n 5
15273         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15274         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15275 }
15276 run_test 160c "verify that changelog log catch the truncate event"
15277
15278 test_160d() {
15279         remote_mds_nodsh && skip "remote MDS with nodsh"
15280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15282         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15283                 skip "Need MDS version at least 2.7.60"
15284
15285         # Registration step
15286         changelog_register || error "changelog_register failed"
15287
15288         mkdir -p $DIR/$tdir/migrate_dir
15289         changelog_clear 0 || error "changelog_clear failed"
15290
15291         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15292         changelog_dump | tail -n 5
15293         local migrates=$(changelog_dump | grep -c "MIGRT")
15294         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15295 }
15296 run_test 160d "verify that changelog log catch the migrate event"
15297
15298 test_160e() {
15299         remote_mds_nodsh && skip "remote MDS with nodsh"
15300
15301         # Create a user
15302         changelog_register || error "changelog_register failed"
15303
15304         # Delete a future user (expect fail)
15305         local MDT0=$(facet_svc $SINGLEMDS)
15306         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15307         local rc=$?
15308
15309         if [ $rc -eq 0 ]; then
15310                 error "Deleted non-existant user cl77"
15311         elif [ $rc -ne 2 ]; then
15312                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15313         fi
15314
15315         # Clear to a bad index (1 billion should be safe)
15316         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15317         rc=$?
15318
15319         if [ $rc -eq 0 ]; then
15320                 error "Successfully cleared to invalid CL index"
15321         elif [ $rc -ne 22 ]; then
15322                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15323         fi
15324 }
15325 run_test 160e "changelog negative testing (should return errors)"
15326
15327 test_160f() {
15328         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15329         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15330                 skip "Need MDS version at least 2.10.56"
15331
15332         local mdts=$(comma_list $(mdts_nodes))
15333
15334         # Create a user
15335         changelog_register || error "first changelog_register failed"
15336         changelog_register || error "second changelog_register failed"
15337         local cl_users
15338         declare -A cl_user1
15339         declare -A cl_user2
15340         local user_rec1
15341         local user_rec2
15342         local i
15343
15344         # generate some changelog records to accumulate on each MDT
15345         # use all_char because created files should be evenly distributed
15346         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15347                 error "test_mkdir $tdir failed"
15348         log "$(date +%s): creating first files"
15349         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15350                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15351                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15352         done
15353
15354         # check changelogs have been generated
15355         local start=$SECONDS
15356         local idle_time=$((MDSCOUNT * 5 + 5))
15357         local nbcl=$(changelog_dump | wc -l)
15358         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15359
15360         for param in "changelog_max_idle_time=$idle_time" \
15361                      "changelog_gc=1" \
15362                      "changelog_min_gc_interval=2" \
15363                      "changelog_min_free_cat_entries=3"; do
15364                 local MDT0=$(facet_svc $SINGLEMDS)
15365                 local var="${param%=*}"
15366                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15367
15368                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15369                 do_nodes $mdts $LCTL set_param mdd.*.$param
15370         done
15371
15372         # force cl_user2 to be idle (1st part), but also cancel the
15373         # cl_user1 records so that it is not evicted later in the test.
15374         local sleep1=$((idle_time / 2))
15375         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15376         sleep $sleep1
15377
15378         # simulate changelog catalog almost full
15379         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15380         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15381
15382         for i in $(seq $MDSCOUNT); do
15383                 cl_users=(${CL_USERS[mds$i]})
15384                 cl_user1[mds$i]="${cl_users[0]}"
15385                 cl_user2[mds$i]="${cl_users[1]}"
15386
15387                 [ -n "${cl_user1[mds$i]}" ] ||
15388                         error "mds$i: no user registered"
15389                 [ -n "${cl_user2[mds$i]}" ] ||
15390                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15391
15392                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15393                 [ -n "$user_rec1" ] ||
15394                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15395                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15396                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15397                 [ -n "$user_rec2" ] ||
15398                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15399                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15400                      "$user_rec1 + 2 == $user_rec2"
15401                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15402                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15403                               "$user_rec1 + 2, but is $user_rec2"
15404                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15405                 [ -n "$user_rec2" ] ||
15406                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15407                 [ $user_rec1 == $user_rec2 ] ||
15408                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15409                               "$user_rec1, but is $user_rec2"
15410         done
15411
15412         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15413         local sleep2=$((idle_time - (SECONDS - start) + 1))
15414         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15415         sleep $sleep2
15416
15417         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15418         # cl_user1 should be OK because it recently processed records.
15419         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15420         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15421                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15422                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15423         done
15424
15425         # ensure gc thread is done
15426         for i in $(mdts_nodes); do
15427                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15428                         error "$i: GC-thread not done"
15429         done
15430
15431         local first_rec
15432         for (( i = 1; i <= MDSCOUNT; i++ )); do
15433                 # check cl_user1 still registered
15434                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15435                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15436                 # check cl_user2 unregistered
15437                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15438                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15439
15440                 # check changelogs are present and starting at $user_rec1 + 1
15441                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15442                 [ -n "$user_rec1" ] ||
15443                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15444                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15445                             awk '{ print $1; exit; }')
15446
15447                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15448                 [ $((user_rec1 + 1)) == $first_rec ] ||
15449                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15450         done
15451 }
15452 run_test 160f "changelog garbage collect (timestamped users)"
15453
15454 test_160g() {
15455         remote_mds_nodsh && skip "remote MDS with nodsh"
15456         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15457                 skip "Need MDS version at least 2.10.56"
15458
15459         local mdts=$(comma_list $(mdts_nodes))
15460
15461         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15462         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15463
15464         # Create a user
15465         changelog_register || error "first changelog_register failed"
15466         changelog_register || error "second changelog_register failed"
15467         local cl_users
15468         declare -A cl_user1
15469         declare -A cl_user2
15470         local user_rec1
15471         local user_rec2
15472         local i
15473
15474         # generate some changelog records to accumulate on each MDT
15475         # use all_char because created files should be evenly distributed
15476         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15477                 error "test_mkdir $tdir failed"
15478         for ((i = 0; i < MDSCOUNT; i++)); do
15479                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15480                         error "create $DIR/$tdir/d$i.1 failed"
15481         done
15482
15483         # check changelogs have been generated
15484         local nbcl=$(changelog_dump | wc -l)
15485         (( $nbcl > 0 )) || error "no changelogs found"
15486
15487         # reduce the max_idle_indexes value to make sure we exceed it
15488         for param in "changelog_max_idle_indexes=1" \
15489                      "changelog_gc=1" \
15490                      "changelog_min_gc_interval=2" \
15491                      "changelog_min_free_cat_entries=3"; do
15492                 local MDT0=$(facet_svc $SINGLEMDS)
15493                 local var="${param%=*}"
15494                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15495
15496                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15497                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15498                         error "unable to set mdd.*.$param"
15499         done
15500
15501         # simulate changelog catalog almost full
15502         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15503         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15504
15505         local start=$SECONDS
15506         for i in $(seq $MDSCOUNT); do
15507                 cl_users=(${CL_USERS[mds$i]})
15508                 cl_user1[mds$i]="${cl_users[0]}"
15509                 cl_user2[mds$i]="${cl_users[1]}"
15510
15511                 [ -n "${cl_user1[mds$i]}" ] ||
15512                         error "mds$i: no user registered"
15513                 [ -n "${cl_user2[mds$i]}" ] ||
15514                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15515
15516                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15517                 [ -n "$user_rec1" ] ||
15518                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15519                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15520                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15521                 [ -n "$user_rec2" ] ||
15522                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15523                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15524                      "$user_rec1 + 2 == $user_rec2"
15525                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15526                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15527                               "$user_rec1 + 2, but is $user_rec2"
15528                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15529                 [ -n "$user_rec2" ] ||
15530                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15531                 [ $user_rec1 == $user_rec2 ] ||
15532                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15533                               "$user_rec1, but is $user_rec2"
15534         done
15535
15536         # ensure we are past the previous changelog_min_gc_interval set above
15537         local sleep2=$((start + 2 - SECONDS))
15538         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15539
15540         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15541         # cl_user1 should be OK because it recently processed records.
15542         for ((i = 0; i < MDSCOUNT; i++)); do
15543                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15544                         error "create $DIR/$tdir/d$i.3 failed"
15545         done
15546
15547         # ensure gc thread is done
15548         for i in $(mdts_nodes); do
15549                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15550                         error "$i: GC-thread not done"
15551         done
15552
15553         local first_rec
15554         for (( i = 1; i <= MDSCOUNT; i++ )); do
15555                 # check cl_user1 still registered
15556                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15557                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15558                 # check cl_user2 unregistered
15559                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15560                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15561
15562                 # check changelogs are present and starting at $user_rec1 + 1
15563                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15564                 [ -n "$user_rec1" ] ||
15565                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15566                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15567                             awk '{ print $1; exit; }')
15568
15569                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15570                 [ $((user_rec1 + 1)) == $first_rec ] ||
15571                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15572         done
15573 }
15574 run_test 160g "changelog garbage collect (old users)"
15575
15576 test_160h() {
15577         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15578         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15579                 skip "Need MDS version at least 2.10.56"
15580
15581         local mdts=$(comma_list $(mdts_nodes))
15582
15583         # Create a user
15584         changelog_register || error "first changelog_register failed"
15585         changelog_register || error "second changelog_register failed"
15586         local cl_users
15587         declare -A cl_user1
15588         declare -A cl_user2
15589         local user_rec1
15590         local user_rec2
15591         local i
15592
15593         # generate some changelog records to accumulate on each MDT
15594         # use all_char because created files should be evenly distributed
15595         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15596                 error "test_mkdir $tdir failed"
15597         for ((i = 0; i < MDSCOUNT; i++)); do
15598                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15599                         error "create $DIR/$tdir/d$i.1 failed"
15600         done
15601
15602         # check changelogs have been generated
15603         local nbcl=$(changelog_dump | wc -l)
15604         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15605
15606         for param in "changelog_max_idle_time=10" \
15607                      "changelog_gc=1" \
15608                      "changelog_min_gc_interval=2"; do
15609                 local MDT0=$(facet_svc $SINGLEMDS)
15610                 local var="${param%=*}"
15611                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15612
15613                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15614                 do_nodes $mdts $LCTL set_param mdd.*.$param
15615         done
15616
15617         # force cl_user2 to be idle (1st part)
15618         sleep 9
15619
15620         for i in $(seq $MDSCOUNT); do
15621                 cl_users=(${CL_USERS[mds$i]})
15622                 cl_user1[mds$i]="${cl_users[0]}"
15623                 cl_user2[mds$i]="${cl_users[1]}"
15624
15625                 [ -n "${cl_user1[mds$i]}" ] ||
15626                         error "mds$i: no user registered"
15627                 [ -n "${cl_user2[mds$i]}" ] ||
15628                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15629
15630                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15631                 [ -n "$user_rec1" ] ||
15632                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15633                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15634                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15635                 [ -n "$user_rec2" ] ||
15636                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15637                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15638                      "$user_rec1 + 2 == $user_rec2"
15639                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15640                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15641                               "$user_rec1 + 2, but is $user_rec2"
15642                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15643                 [ -n "$user_rec2" ] ||
15644                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15645                 [ $user_rec1 == $user_rec2 ] ||
15646                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15647                               "$user_rec1, but is $user_rec2"
15648         done
15649
15650         # force cl_user2 to be idle (2nd part) and to reach
15651         # changelog_max_idle_time
15652         sleep 2
15653
15654         # force each GC-thread start and block then
15655         # one per MDT/MDD, set fail_val accordingly
15656         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15657         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15658
15659         # generate more changelogs to trigger fail_loc
15660         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15661                 error "create $DIR/$tdir/${tfile}bis failed"
15662
15663         # stop MDT to stop GC-thread, should be done in back-ground as it will
15664         # block waiting for the thread to be released and exit
15665         declare -A stop_pids
15666         for i in $(seq $MDSCOUNT); do
15667                 stop mds$i &
15668                 stop_pids[mds$i]=$!
15669         done
15670
15671         for i in $(mdts_nodes); do
15672                 local facet
15673                 local nb=0
15674                 local facets=$(facets_up_on_host $i)
15675
15676                 for facet in ${facets//,/ }; do
15677                         if [[ $facet == mds* ]]; then
15678                                 nb=$((nb + 1))
15679                         fi
15680                 done
15681                 # ensure each MDS's gc threads are still present and all in "R"
15682                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15683                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15684                         error "$i: expected $nb GC-thread"
15685                 wait_update $i \
15686                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15687                         "R" 20 ||
15688                         error "$i: GC-thread not found in R-state"
15689                 # check umounts of each MDT on MDS have reached kthread_stop()
15690                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15691                         error "$i: expected $nb umount"
15692                 wait_update $i \
15693                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15694                         error "$i: umount not found in D-state"
15695         done
15696
15697         # release all GC-threads
15698         do_nodes $mdts $LCTL set_param fail_loc=0
15699
15700         # wait for MDT stop to complete
15701         for i in $(seq $MDSCOUNT); do
15702                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15703         done
15704
15705         # XXX
15706         # may try to check if any orphan changelog records are present
15707         # via ldiskfs/zfs and llog_reader...
15708
15709         # re-start/mount MDTs
15710         for i in $(seq $MDSCOUNT); do
15711                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15712                         error "Fail to start mds$i"
15713         done
15714
15715         local first_rec
15716         for i in $(seq $MDSCOUNT); do
15717                 # check cl_user1 still registered
15718                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15719                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15720                 # check cl_user2 unregistered
15721                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15722                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15723
15724                 # check changelogs are present and starting at $user_rec1 + 1
15725                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15726                 [ -n "$user_rec1" ] ||
15727                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15728                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15729                             awk '{ print $1; exit; }')
15730
15731                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15732                 [ $((user_rec1 + 1)) == $first_rec ] ||
15733                         error "mds$i: first index should be $user_rec1 + 1, " \
15734                               "but is $first_rec"
15735         done
15736 }
15737 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15738               "during mount"
15739
15740 test_160i() {
15741
15742         local mdts=$(comma_list $(mdts_nodes))
15743
15744         changelog_register || error "first changelog_register failed"
15745
15746         # generate some changelog records to accumulate on each MDT
15747         # use all_char because created files should be evenly distributed
15748         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15749                 error "test_mkdir $tdir failed"
15750         for ((i = 0; i < MDSCOUNT; i++)); do
15751                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15752                         error "create $DIR/$tdir/d$i.1 failed"
15753         done
15754
15755         # check changelogs have been generated
15756         local nbcl=$(changelog_dump | wc -l)
15757         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15758
15759         # simulate race between register and unregister
15760         # XXX as fail_loc is set per-MDS, with DNE configs the race
15761         # simulation will only occur for one MDT per MDS and for the
15762         # others the normal race scenario will take place
15763         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15764         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15765         do_nodes $mdts $LCTL set_param fail_val=1
15766
15767         # unregister 1st user
15768         changelog_deregister &
15769         local pid1=$!
15770         # wait some time for deregister work to reach race rdv
15771         sleep 2
15772         # register 2nd user
15773         changelog_register || error "2nd user register failed"
15774
15775         wait $pid1 || error "1st user deregister failed"
15776
15777         local i
15778         local last_rec
15779         declare -A LAST_REC
15780         for i in $(seq $MDSCOUNT); do
15781                 if changelog_users mds$i | grep "^cl"; then
15782                         # make sure new records are added with one user present
15783                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15784                                           awk '/^current.index:/ { print $NF }')
15785                 else
15786                         error "mds$i has no user registered"
15787                 fi
15788         done
15789
15790         # generate more changelog records to accumulate on each MDT
15791         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15792                 error "create $DIR/$tdir/${tfile}bis failed"
15793
15794         for i in $(seq $MDSCOUNT); do
15795                 last_rec=$(changelog_users $SINGLEMDS |
15796                            awk '/^current.index:/ { print $NF }')
15797                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15798                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15799                         error "changelogs are off on mds$i"
15800         done
15801 }
15802 run_test 160i "changelog user register/unregister race"
15803
15804 test_160j() {
15805         remote_mds_nodsh && skip "remote MDS with nodsh"
15806         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15807                 skip "Need MDS version at least 2.12.56"
15808
15809         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15810         stack_trap "umount $MOUNT2" EXIT
15811
15812         changelog_register || error "first changelog_register failed"
15813         stack_trap "changelog_deregister" EXIT
15814
15815         # generate some changelog
15816         # use all_char because created files should be evenly distributed
15817         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15818                 error "mkdir $tdir failed"
15819         for ((i = 0; i < MDSCOUNT; i++)); do
15820                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15821                         error "create $DIR/$tdir/d$i.1 failed"
15822         done
15823
15824         # open the changelog device
15825         exec 3>/dev/changelog-$FSNAME-MDT0000
15826         stack_trap "exec 3>&-" EXIT
15827         exec 4</dev/changelog-$FSNAME-MDT0000
15828         stack_trap "exec 4<&-" EXIT
15829
15830         # umount the first lustre mount
15831         umount $MOUNT
15832         stack_trap "mount_client $MOUNT" EXIT
15833
15834         # read changelog, which may or may not fail, but should not crash
15835         cat <&4 >/dev/null
15836
15837         # clear changelog
15838         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15839         changelog_users $SINGLEMDS | grep -q $cl_user ||
15840                 error "User $cl_user not found in changelog_users"
15841
15842         printf 'clear:'$cl_user':0' >&3
15843 }
15844 run_test 160j "client can be umounted while its chanangelog is being used"
15845
15846 test_160k() {
15847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15848         remote_mds_nodsh && skip "remote MDS with nodsh"
15849
15850         mkdir -p $DIR/$tdir/1/1
15851
15852         changelog_register || error "changelog_register failed"
15853         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15854
15855         changelog_users $SINGLEMDS | grep -q $cl_user ||
15856                 error "User '$cl_user' not found in changelog_users"
15857 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15858         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15859         rmdir $DIR/$tdir/1/1 & sleep 1
15860         mkdir $DIR/$tdir/2
15861         touch $DIR/$tdir/2/2
15862         rm -rf $DIR/$tdir/2
15863
15864         wait
15865         sleep 4
15866
15867         changelog_dump | grep rmdir || error "rmdir not recorded"
15868 }
15869 run_test 160k "Verify that changelog records are not lost"
15870
15871 # Verifies that a file passed as a parameter has recently had an operation
15872 # performed on it that has generated an MTIME changelog which contains the
15873 # correct parent FID. As files might reside on a different MDT from the
15874 # parent directory in DNE configurations, the FIDs are translated to paths
15875 # before being compared, which should be identical
15876 compare_mtime_changelog() {
15877         local file="${1}"
15878         local mdtidx
15879         local mtime
15880         local cl_fid
15881         local pdir
15882         local dir
15883
15884         mdtidx=$($LFS getstripe --mdt-index $file)
15885         mdtidx=$(printf "%04x" $mdtidx)
15886
15887         # Obtain the parent FID from the MTIME changelog
15888         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15889         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15890
15891         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15892         [ -z "$cl_fid" ] && error "parent FID not present"
15893
15894         # Verify that the path for the parent FID is the same as the path for
15895         # the test directory
15896         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15897
15898         dir=$(dirname $1)
15899
15900         [[ "${pdir%/}" == "$dir" ]] ||
15901                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15902 }
15903
15904 test_160l() {
15905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15906
15907         remote_mds_nodsh && skip "remote MDS with nodsh"
15908         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15909                 skip "Need MDS version at least 2.13.55"
15910
15911         local cl_user
15912
15913         changelog_register || error "changelog_register failed"
15914         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15915
15916         changelog_users $SINGLEMDS | grep -q $cl_user ||
15917                 error "User '$cl_user' not found in changelog_users"
15918
15919         # Clear some types so that MTIME changelogs are generated
15920         changelog_chmask "-CREAT"
15921         changelog_chmask "-CLOSE"
15922
15923         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15924
15925         # Test CL_MTIME during setattr
15926         touch $DIR/$tdir/$tfile
15927         compare_mtime_changelog $DIR/$tdir/$tfile
15928
15929         # Test CL_MTIME during close
15930         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15931         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15932 }
15933 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15934
15935 test_160m() {
15936         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15937         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15938                 skip "Need MDS version at least 2.14.51"
15939         local cl_users
15940         local cl_user1
15941         local cl_user2
15942         local pid1
15943
15944         # Create a user
15945         changelog_register || error "first changelog_register failed"
15946         changelog_register || error "second changelog_register failed"
15947
15948         cl_users=(${CL_USERS[mds1]})
15949         cl_user1="${cl_users[0]}"
15950         cl_user2="${cl_users[1]}"
15951         # generate some changelog records to accumulate on MDT0
15952         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15953         createmany -m $DIR/$tdir/$tfile 50 ||
15954                 error "create $DIR/$tdir/$tfile failed"
15955         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15956         rm -f $DIR/$tdir
15957
15958         # check changelogs have been generated
15959         local nbcl=$(changelog_dump | wc -l)
15960         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15961
15962 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15963         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15964
15965         __changelog_clear mds1 $cl_user1 +10
15966         __changelog_clear mds1 $cl_user2 0 &
15967         pid1=$!
15968         sleep 2
15969         __changelog_clear mds1 $cl_user1 0 ||
15970                 error "fail to cancel record for $cl_user1"
15971         wait $pid1
15972         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15973 }
15974 run_test 160m "Changelog clear race"
15975
15976
15977 test_161a() {
15978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15979
15980         test_mkdir -c1 $DIR/$tdir
15981         cp /etc/hosts $DIR/$tdir/$tfile
15982         test_mkdir -c1 $DIR/$tdir/foo1
15983         test_mkdir -c1 $DIR/$tdir/foo2
15984         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15985         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15986         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15987         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15988         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15989         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15990                 $LFS fid2path $DIR $FID
15991                 error "bad link ea"
15992         fi
15993         # middle
15994         rm $DIR/$tdir/foo2/zachary
15995         # last
15996         rm $DIR/$tdir/foo2/thor
15997         # first
15998         rm $DIR/$tdir/$tfile
15999         # rename
16000         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16001         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16002                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16003         rm $DIR/$tdir/foo2/maggie
16004
16005         # overflow the EA
16006         local longname=$tfile.avg_len_is_thirty_two_
16007         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16008                 error_noexit 'failed to unlink many hardlinks'" EXIT
16009         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16010                 error "failed to hardlink many files"
16011         links=$($LFS fid2path $DIR $FID | wc -l)
16012         echo -n "${links}/1000 links in link EA"
16013         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16014 }
16015 run_test 161a "link ea sanity"
16016
16017 test_161b() {
16018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16019         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16020
16021         local MDTIDX=1
16022         local remote_dir=$DIR/$tdir/remote_dir
16023
16024         mkdir -p $DIR/$tdir
16025         $LFS mkdir -i $MDTIDX $remote_dir ||
16026                 error "create remote directory failed"
16027
16028         cp /etc/hosts $remote_dir/$tfile
16029         mkdir -p $remote_dir/foo1
16030         mkdir -p $remote_dir/foo2
16031         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16032         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16033         ln $remote_dir/$tfile $remote_dir/foo1/luna
16034         ln $remote_dir/$tfile $remote_dir/foo2/thor
16035
16036         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16037                      tr -d ']')
16038         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16039                 $LFS fid2path $DIR $FID
16040                 error "bad link ea"
16041         fi
16042         # middle
16043         rm $remote_dir/foo2/zachary
16044         # last
16045         rm $remote_dir/foo2/thor
16046         # first
16047         rm $remote_dir/$tfile
16048         # rename
16049         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16050         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16051         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16052                 $LFS fid2path $DIR $FID
16053                 error "bad link rename"
16054         fi
16055         rm $remote_dir/foo2/maggie
16056
16057         # overflow the EA
16058         local longname=filename_avg_len_is_thirty_two_
16059         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16060                 error "failed to hardlink many files"
16061         links=$($LFS fid2path $DIR $FID | wc -l)
16062         echo -n "${links}/1000 links in link EA"
16063         [[ ${links} -gt 60 ]] ||
16064                 error "expected at least 60 links in link EA"
16065         unlinkmany $remote_dir/foo2/$longname 1000 ||
16066         error "failed to unlink many hardlinks"
16067 }
16068 run_test 161b "link ea sanity under remote directory"
16069
16070 test_161c() {
16071         remote_mds_nodsh && skip "remote MDS with nodsh"
16072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16073         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16074                 skip "Need MDS version at least 2.1.5"
16075
16076         # define CLF_RENAME_LAST 0x0001
16077         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16078         changelog_register || error "changelog_register failed"
16079
16080         rm -rf $DIR/$tdir
16081         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16082         touch $DIR/$tdir/foo_161c
16083         touch $DIR/$tdir/bar_161c
16084         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16085         changelog_dump | grep RENME | tail -n 5
16086         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16087         changelog_clear 0 || error "changelog_clear failed"
16088         if [ x$flags != "x0x1" ]; then
16089                 error "flag $flags is not 0x1"
16090         fi
16091
16092         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16093         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16094         touch $DIR/$tdir/foo_161c
16095         touch $DIR/$tdir/bar_161c
16096         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16097         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16098         changelog_dump | grep RENME | tail -n 5
16099         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16100         changelog_clear 0 || error "changelog_clear failed"
16101         if [ x$flags != "x0x0" ]; then
16102                 error "flag $flags is not 0x0"
16103         fi
16104         echo "rename overwrite a target having nlink > 1," \
16105                 "changelog record has flags of $flags"
16106
16107         # rename doesn't overwrite a target (changelog flag 0x0)
16108         touch $DIR/$tdir/foo_161c
16109         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16110         changelog_dump | grep RENME | tail -n 5
16111         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16112         changelog_clear 0 || error "changelog_clear failed"
16113         if [ x$flags != "x0x0" ]; then
16114                 error "flag $flags is not 0x0"
16115         fi
16116         echo "rename doesn't overwrite a target," \
16117                 "changelog record has flags of $flags"
16118
16119         # define CLF_UNLINK_LAST 0x0001
16120         # unlink a file having nlink = 1 (changelog flag 0x1)
16121         rm -f $DIR/$tdir/foo2_161c
16122         changelog_dump | grep UNLNK | tail -n 5
16123         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16124         changelog_clear 0 || error "changelog_clear failed"
16125         if [ x$flags != "x0x1" ]; then
16126                 error "flag $flags is not 0x1"
16127         fi
16128         echo "unlink a file having nlink = 1," \
16129                 "changelog record has flags of $flags"
16130
16131         # unlink a file having nlink > 1 (changelog flag 0x0)
16132         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16133         rm -f $DIR/$tdir/foobar_161c
16134         changelog_dump | grep UNLNK | tail -n 5
16135         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16136         changelog_clear 0 || error "changelog_clear failed"
16137         if [ x$flags != "x0x0" ]; then
16138                 error "flag $flags is not 0x0"
16139         fi
16140         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16141 }
16142 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16143
16144 test_161d() {
16145         remote_mds_nodsh && skip "remote MDS with nodsh"
16146         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16147
16148         local pid
16149         local fid
16150
16151         changelog_register || error "changelog_register failed"
16152
16153         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16154         # interfer with $MOUNT/.lustre/fid/ access
16155         mkdir $DIR/$tdir
16156         [[ $? -eq 0 ]] || error "mkdir failed"
16157
16158         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16159         $LCTL set_param fail_loc=0x8000140c
16160         # 5s pause
16161         $LCTL set_param fail_val=5
16162
16163         # create file
16164         echo foofoo > $DIR/$tdir/$tfile &
16165         pid=$!
16166
16167         # wait for create to be delayed
16168         sleep 2
16169
16170         ps -p $pid
16171         [[ $? -eq 0 ]] || error "create should be blocked"
16172
16173         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16174         stack_trap "rm -f $tempfile"
16175         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16176         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16177         # some delay may occur during ChangeLog publishing and file read just
16178         # above, that could allow file write to happen finally
16179         [[ -s $tempfile ]] && echo "file should be empty"
16180
16181         $LCTL set_param fail_loc=0
16182
16183         wait $pid
16184         [[ $? -eq 0 ]] || error "create failed"
16185 }
16186 run_test 161d "create with concurrent .lustre/fid access"
16187
16188 check_path() {
16189         local expected="$1"
16190         shift
16191         local fid="$2"
16192
16193         local path
16194         path=$($LFS fid2path "$@")
16195         local rc=$?
16196
16197         if [ $rc -ne 0 ]; then
16198                 error "path looked up of '$expected' failed: rc=$rc"
16199         elif [ "$path" != "$expected" ]; then
16200                 error "path looked up '$path' instead of '$expected'"
16201         else
16202                 echo "FID '$fid' resolves to path '$path' as expected"
16203         fi
16204 }
16205
16206 test_162a() { # was test_162
16207         test_mkdir -p -c1 $DIR/$tdir/d2
16208         touch $DIR/$tdir/d2/$tfile
16209         touch $DIR/$tdir/d2/x1
16210         touch $DIR/$tdir/d2/x2
16211         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16212         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16213         # regular file
16214         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16215         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16216
16217         # softlink
16218         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16219         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16220         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16221
16222         # softlink to wrong file
16223         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16224         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16225         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16226
16227         # hardlink
16228         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16229         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16230         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16231         # fid2path dir/fsname should both work
16232         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16233         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16234
16235         # hardlink count: check that there are 2 links
16236         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16237         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16238
16239         # hardlink indexing: remove the first link
16240         rm $DIR/$tdir/d2/p/q/r/hlink
16241         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16242 }
16243 run_test 162a "path lookup sanity"
16244
16245 test_162b() {
16246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16248
16249         mkdir $DIR/$tdir
16250         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16251                                 error "create striped dir failed"
16252
16253         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16254                                         tail -n 1 | awk '{print $2}')
16255         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16256
16257         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16258         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16259
16260         # regular file
16261         for ((i=0;i<5;i++)); do
16262                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16263                         error "get fid for f$i failed"
16264                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16265
16266                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16267                         error "get fid for d$i failed"
16268                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16269         done
16270
16271         return 0
16272 }
16273 run_test 162b "striped directory path lookup sanity"
16274
16275 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16276 test_162c() {
16277         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16278                 skip "Need MDS version at least 2.7.51"
16279
16280         local lpath=$tdir.local
16281         local rpath=$tdir.remote
16282
16283         test_mkdir $DIR/$lpath
16284         test_mkdir $DIR/$rpath
16285
16286         for ((i = 0; i <= 101; i++)); do
16287                 lpath="$lpath/$i"
16288                 mkdir $DIR/$lpath
16289                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16290                         error "get fid for local directory $DIR/$lpath failed"
16291                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16292
16293                 rpath="$rpath/$i"
16294                 test_mkdir $DIR/$rpath
16295                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16296                         error "get fid for remote directory $DIR/$rpath failed"
16297                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16298         done
16299
16300         return 0
16301 }
16302 run_test 162c "fid2path works with paths 100 or more directories deep"
16303
16304 oalr_event_count() {
16305         local event="${1}"
16306         local trace="${2}"
16307
16308         awk -v name="${FSNAME}-OST0000" \
16309             -v event="${event}" \
16310             '$1 == "TRACE" && $2 == event && $3 == name' \
16311             "${trace}" |
16312         wc -l
16313 }
16314
16315 oalr_expect_event_count() {
16316         local event="${1}"
16317         local trace="${2}"
16318         local expect="${3}"
16319         local count
16320
16321         count=$(oalr_event_count "${event}" "${trace}")
16322         if ((count == expect)); then
16323                 return 0
16324         fi
16325
16326         error_noexit "${event} event count was '${count}', expected ${expect}"
16327         cat "${trace}" >&2
16328         exit 1
16329 }
16330
16331 cleanup_165() {
16332         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16333         stop ost1
16334         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16335 }
16336
16337 setup_165() {
16338         sync # Flush previous IOs so we can count log entries.
16339         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16340         stack_trap cleanup_165 EXIT
16341 }
16342
16343 test_165a() {
16344         local trace="/tmp/${tfile}.trace"
16345         local rc
16346         local count
16347
16348         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16349                 skip "OFD access log unsupported"
16350
16351         setup_165
16352         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16353         sleep 5
16354
16355         do_facet ost1 ofd_access_log_reader --list
16356         stop ost1
16357
16358         do_facet ost1 killall -TERM ofd_access_log_reader
16359         wait
16360         rc=$?
16361
16362         if ((rc != 0)); then
16363                 error "ofd_access_log_reader exited with rc = '${rc}'"
16364         fi
16365
16366         # Parse trace file for discovery events:
16367         oalr_expect_event_count alr_log_add "${trace}" 1
16368         oalr_expect_event_count alr_log_eof "${trace}" 1
16369         oalr_expect_event_count alr_log_free "${trace}" 1
16370 }
16371 run_test 165a "ofd access log discovery"
16372
16373 test_165b() {
16374         local trace="/tmp/${tfile}.trace"
16375         local file="${DIR}/${tfile}"
16376         local pfid1
16377         local pfid2
16378         local -a entry
16379         local rc
16380         local count
16381         local size
16382         local flags
16383
16384         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16385                 skip "OFD access log unsupported"
16386
16387         setup_165
16388         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16389         sleep 5
16390
16391         do_facet ost1 ofd_access_log_reader --list
16392
16393         lfs setstripe -c 1 -i 0 "${file}"
16394         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16395                 error "cannot create '${file}'"
16396
16397         sleep 5
16398         do_facet ost1 killall -TERM ofd_access_log_reader
16399         wait
16400         rc=$?
16401
16402         if ((rc != 0)); then
16403                 error "ofd_access_log_reader exited with rc = '${rc}'"
16404         fi
16405
16406         oalr_expect_event_count alr_log_entry "${trace}" 1
16407
16408         pfid1=$($LFS path2fid "${file}")
16409
16410         # 1     2             3   4    5     6   7    8    9     10
16411         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16412         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16413
16414         echo "entry = '${entry[*]}'" >&2
16415
16416         pfid2=${entry[4]}
16417         if [[ "${pfid1}" != "${pfid2}" ]]; then
16418                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16419         fi
16420
16421         size=${entry[8]}
16422         if ((size != 1048576)); then
16423                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16424         fi
16425
16426         flags=${entry[10]}
16427         if [[ "${flags}" != "w" ]]; then
16428                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16429         fi
16430
16431         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16432         sleep 5
16433
16434         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16435                 error "cannot read '${file}'"
16436         sleep 5
16437
16438         do_facet ost1 killall -TERM ofd_access_log_reader
16439         wait
16440         rc=$?
16441
16442         if ((rc != 0)); then
16443                 error "ofd_access_log_reader exited with rc = '${rc}'"
16444         fi
16445
16446         oalr_expect_event_count alr_log_entry "${trace}" 1
16447
16448         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16449         echo "entry = '${entry[*]}'" >&2
16450
16451         pfid2=${entry[4]}
16452         if [[ "${pfid1}" != "${pfid2}" ]]; then
16453                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16454         fi
16455
16456         size=${entry[8]}
16457         if ((size != 524288)); then
16458                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16459         fi
16460
16461         flags=${entry[10]}
16462         if [[ "${flags}" != "r" ]]; then
16463                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16464         fi
16465 }
16466 run_test 165b "ofd access log entries are produced and consumed"
16467
16468 test_165c() {
16469         local trace="/tmp/${tfile}.trace"
16470         local file="${DIR}/${tdir}/${tfile}"
16471
16472         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16473                 skip "OFD access log unsupported"
16474
16475         test_mkdir "${DIR}/${tdir}"
16476
16477         setup_165
16478         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16479         sleep 5
16480
16481         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16482
16483         # 4096 / 64 = 64. Create twice as many entries.
16484         for ((i = 0; i < 128; i++)); do
16485                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16486                         error "cannot create file"
16487         done
16488
16489         sync
16490
16491         do_facet ost1 killall -TERM ofd_access_log_reader
16492         wait
16493         rc=$?
16494         if ((rc != 0)); then
16495                 error "ofd_access_log_reader exited with rc = '${rc}'"
16496         fi
16497
16498         unlinkmany  "${file}-%d" 128
16499 }
16500 run_test 165c "full ofd access logs do not block IOs"
16501
16502 oal_get_read_count() {
16503         local stats="$1"
16504
16505         # STATS lustre-OST0001 alr_read_count 1
16506
16507         do_facet ost1 cat "${stats}" |
16508         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16509              END { print count; }'
16510 }
16511
16512 oal_expect_read_count() {
16513         local stats="$1"
16514         local count
16515         local expect="$2"
16516
16517         # Ask ofd_access_log_reader to write stats.
16518         do_facet ost1 killall -USR1 ofd_access_log_reader
16519
16520         # Allow some time for things to happen.
16521         sleep 1
16522
16523         count=$(oal_get_read_count "${stats}")
16524         if ((count == expect)); then
16525                 return 0
16526         fi
16527
16528         error_noexit "bad read count, got ${count}, expected ${expect}"
16529         do_facet ost1 cat "${stats}" >&2
16530         exit 1
16531 }
16532
16533 test_165d() {
16534         local stats="/tmp/${tfile}.stats"
16535         local file="${DIR}/${tdir}/${tfile}"
16536         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16537
16538         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16539                 skip "OFD access log unsupported"
16540
16541         test_mkdir "${DIR}/${tdir}"
16542
16543         setup_165
16544         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16545         sleep 5
16546
16547         lfs setstripe -c 1 -i 0 "${file}"
16548
16549         do_facet ost1 lctl set_param "${param}=rw"
16550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16551                 error "cannot create '${file}'"
16552         oal_expect_read_count "${stats}" 1
16553
16554         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16555                 error "cannot read '${file}'"
16556         oal_expect_read_count "${stats}" 2
16557
16558         do_facet ost1 lctl set_param "${param}=r"
16559         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16560                 error "cannot create '${file}'"
16561         oal_expect_read_count "${stats}" 2
16562
16563         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16564                 error "cannot read '${file}'"
16565         oal_expect_read_count "${stats}" 3
16566
16567         do_facet ost1 lctl set_param "${param}=w"
16568         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16569                 error "cannot create '${file}'"
16570         oal_expect_read_count "${stats}" 4
16571
16572         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16573                 error "cannot read '${file}'"
16574         oal_expect_read_count "${stats}" 4
16575
16576         do_facet ost1 lctl set_param "${param}=0"
16577         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16578                 error "cannot create '${file}'"
16579         oal_expect_read_count "${stats}" 4
16580
16581         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16582                 error "cannot read '${file}'"
16583         oal_expect_read_count "${stats}" 4
16584
16585         do_facet ost1 killall -TERM ofd_access_log_reader
16586         wait
16587         rc=$?
16588         if ((rc != 0)); then
16589                 error "ofd_access_log_reader exited with rc = '${rc}'"
16590         fi
16591 }
16592 run_test 165d "ofd_access_log mask works"
16593
16594 test_165e() {
16595         local stats="/tmp/${tfile}.stats"
16596         local file0="${DIR}/${tdir}-0/${tfile}"
16597         local file1="${DIR}/${tdir}-1/${tfile}"
16598
16599         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16600                 skip "OFD access log unsupported"
16601
16602         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16603
16604         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16605         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16606
16607         lfs setstripe -c 1 -i 0 "${file0}"
16608         lfs setstripe -c 1 -i 0 "${file1}"
16609
16610         setup_165
16611         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16612         sleep 5
16613
16614         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16615                 error "cannot create '${file0}'"
16616         sync
16617         oal_expect_read_count "${stats}" 0
16618
16619         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16620                 error "cannot create '${file1}'"
16621         sync
16622         oal_expect_read_count "${stats}" 1
16623
16624         do_facet ost1 killall -TERM ofd_access_log_reader
16625         wait
16626         rc=$?
16627         if ((rc != 0)); then
16628                 error "ofd_access_log_reader exited with rc = '${rc}'"
16629         fi
16630 }
16631 run_test 165e "ofd_access_log MDT index filter works"
16632
16633 test_165f() {
16634         local trace="/tmp/${tfile}.trace"
16635         local rc
16636         local count
16637
16638         setup_165
16639         do_facet ost1 timeout 60 ofd_access_log_reader \
16640                 --exit-on-close --debug=- --trace=- > "${trace}" &
16641         sleep 5
16642         stop ost1
16643
16644         wait
16645         rc=$?
16646
16647         if ((rc != 0)); then
16648                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16649                 cat "${trace}"
16650                 exit 1
16651         fi
16652 }
16653 run_test 165f "ofd_access_log_reader --exit-on-close works"
16654
16655 test_169() {
16656         # do directio so as not to populate the page cache
16657         log "creating a 10 Mb file"
16658         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16659                 error "multiop failed while creating a file"
16660         log "starting reads"
16661         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16662         log "truncating the file"
16663         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16664                 error "multiop failed while truncating the file"
16665         log "killing dd"
16666         kill %+ || true # reads might have finished
16667         echo "wait until dd is finished"
16668         wait
16669         log "removing the temporary file"
16670         rm -rf $DIR/$tfile || error "tmp file removal failed"
16671 }
16672 run_test 169 "parallel read and truncate should not deadlock"
16673
16674 test_170() {
16675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16676
16677         $LCTL clear     # bug 18514
16678         $LCTL debug_daemon start $TMP/${tfile}_log_good
16679         touch $DIR/$tfile
16680         $LCTL debug_daemon stop
16681         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16682                 error "sed failed to read log_good"
16683
16684         $LCTL debug_daemon start $TMP/${tfile}_log_good
16685         rm -rf $DIR/$tfile
16686         $LCTL debug_daemon stop
16687
16688         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16689                error "lctl df log_bad failed"
16690
16691         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16692         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16693
16694         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16695         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16696
16697         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16698                 error "bad_line good_line1 good_line2 are empty"
16699
16700         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16701         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16702         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16703
16704         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16705         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16706         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16707
16708         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16709                 error "bad_line_new good_line_new are empty"
16710
16711         local expected_good=$((good_line1 + good_line2*2))
16712
16713         rm -f $TMP/${tfile}*
16714         # LU-231, short malformed line may not be counted into bad lines
16715         if [ $bad_line -ne $bad_line_new ] &&
16716                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16717                 error "expected $bad_line bad lines, but got $bad_line_new"
16718                 return 1
16719         fi
16720
16721         if [ $expected_good -ne $good_line_new ]; then
16722                 error "expected $expected_good good lines, but got $good_line_new"
16723                 return 2
16724         fi
16725         true
16726 }
16727 run_test 170 "test lctl df to handle corrupted log ====================="
16728
16729 test_171() { # bug20592
16730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16731
16732         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16733         $LCTL set_param fail_loc=0x50e
16734         $LCTL set_param fail_val=3000
16735         multiop_bg_pause $DIR/$tfile O_s || true
16736         local MULTIPID=$!
16737         kill -USR1 $MULTIPID
16738         # cause log dump
16739         sleep 3
16740         wait $MULTIPID
16741         if dmesg | grep "recursive fault"; then
16742                 error "caught a recursive fault"
16743         fi
16744         $LCTL set_param fail_loc=0
16745         true
16746 }
16747 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16748
16749 # it would be good to share it with obdfilter-survey/iokit-libecho code
16750 setup_obdecho_osc () {
16751         local rc=0
16752         local ost_nid=$1
16753         local obdfilter_name=$2
16754         echo "Creating new osc for $obdfilter_name on $ost_nid"
16755         # make sure we can find loopback nid
16756         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16757
16758         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16759                            ${obdfilter_name}_osc_UUID || rc=2; }
16760         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16761                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16762         return $rc
16763 }
16764
16765 cleanup_obdecho_osc () {
16766         local obdfilter_name=$1
16767         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16768         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16769         return 0
16770 }
16771
16772 obdecho_test() {
16773         local OBD=$1
16774         local node=$2
16775         local pages=${3:-64}
16776         local rc=0
16777         local id
16778
16779         local count=10
16780         local obd_size=$(get_obd_size $node $OBD)
16781         local page_size=$(get_page_size $node)
16782         if [[ -n "$obd_size" ]]; then
16783                 local new_count=$((obd_size / (pages * page_size / 1024)))
16784                 [[ $new_count -ge $count ]] || count=$new_count
16785         fi
16786
16787         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16788         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16789                            rc=2; }
16790         if [ $rc -eq 0 ]; then
16791             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16792             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16793         fi
16794         echo "New object id is $id"
16795         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16796                            rc=4; }
16797         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16798                            "test_brw $count w v $pages $id" || rc=4; }
16799         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16800                            rc=4; }
16801         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16802                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16803         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16804                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16805         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16806         return $rc
16807 }
16808
16809 test_180a() {
16810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16811
16812         if ! [ -d /sys/fs/lustre/echo_client ] &&
16813            ! module_loaded obdecho; then
16814                 load_module obdecho/obdecho &&
16815                         stack_trap "rmmod obdecho" EXIT ||
16816                         error "unable to load obdecho on client"
16817         fi
16818
16819         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16820         local host=$($LCTL get_param -n osc.$osc.import |
16821                      awk '/current_connection:/ { print $2 }' )
16822         local target=$($LCTL get_param -n osc.$osc.import |
16823                        awk '/target:/ { print $2 }' )
16824         target=${target%_UUID}
16825
16826         if [ -n "$target" ]; then
16827                 setup_obdecho_osc $host $target &&
16828                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16829                         { error "obdecho setup failed with $?"; return; }
16830
16831                 obdecho_test ${target}_osc client ||
16832                         error "obdecho_test failed on ${target}_osc"
16833         else
16834                 $LCTL get_param osc.$osc.import
16835                 error "there is no osc.$osc.import target"
16836         fi
16837 }
16838 run_test 180a "test obdecho on osc"
16839
16840 test_180b() {
16841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16842         remote_ost_nodsh && skip "remote OST with nodsh"
16843
16844         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16845                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16846                 error "failed to load module obdecho"
16847
16848         local target=$(do_facet ost1 $LCTL dl |
16849                        awk '/obdfilter/ { print $4; exit; }')
16850
16851         if [ -n "$target" ]; then
16852                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16853         else
16854                 do_facet ost1 $LCTL dl
16855                 error "there is no obdfilter target on ost1"
16856         fi
16857 }
16858 run_test 180b "test obdecho directly on obdfilter"
16859
16860 test_180c() { # LU-2598
16861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16862         remote_ost_nodsh && skip "remote OST with nodsh"
16863         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16864                 skip "Need MDS version at least 2.4.0"
16865
16866         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16867                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16868                 error "failed to load module obdecho"
16869
16870         local target=$(do_facet ost1 $LCTL dl |
16871                        awk '/obdfilter/ { print $4; exit; }')
16872
16873         if [ -n "$target" ]; then
16874                 local pages=16384 # 64MB bulk I/O RPC size
16875
16876                 obdecho_test "$target" ost1 "$pages" ||
16877                         error "obdecho_test with pages=$pages failed with $?"
16878         else
16879                 do_facet ost1 $LCTL dl
16880                 error "there is no obdfilter target on ost1"
16881         fi
16882 }
16883 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16884
16885 test_181() { # bug 22177
16886         test_mkdir $DIR/$tdir
16887         # create enough files to index the directory
16888         createmany -o $DIR/$tdir/foobar 4000
16889         # print attributes for debug purpose
16890         lsattr -d .
16891         # open dir
16892         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16893         MULTIPID=$!
16894         # remove the files & current working dir
16895         unlinkmany $DIR/$tdir/foobar 4000
16896         rmdir $DIR/$tdir
16897         kill -USR1 $MULTIPID
16898         wait $MULTIPID
16899         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16900         return 0
16901 }
16902 run_test 181 "Test open-unlinked dir ========================"
16903
16904 test_182() {
16905         local fcount=1000
16906         local tcount=10
16907
16908         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16909
16910         $LCTL set_param mdc.*.rpc_stats=clear
16911
16912         for (( i = 0; i < $tcount; i++ )) ; do
16913                 mkdir $DIR/$tdir/$i
16914         done
16915
16916         for (( i = 0; i < $tcount; i++ )) ; do
16917                 createmany -o $DIR/$tdir/$i/f- $fcount &
16918         done
16919         wait
16920
16921         for (( i = 0; i < $tcount; i++ )) ; do
16922                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16923         done
16924         wait
16925
16926         $LCTL get_param mdc.*.rpc_stats
16927
16928         rm -rf $DIR/$tdir
16929 }
16930 run_test 182 "Test parallel modify metadata operations ================"
16931
16932 test_183() { # LU-2275
16933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16934         remote_mds_nodsh && skip "remote MDS with nodsh"
16935         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16936                 skip "Need MDS version at least 2.3.56"
16937
16938         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16939         echo aaa > $DIR/$tdir/$tfile
16940
16941 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16942         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16943
16944         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16945         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16946
16947         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16948
16949         # Flush negative dentry cache
16950         touch $DIR/$tdir/$tfile
16951
16952         # We are not checking for any leaked references here, they'll
16953         # become evident next time we do cleanup with module unload.
16954         rm -rf $DIR/$tdir
16955 }
16956 run_test 183 "No crash or request leak in case of strange dispositions ========"
16957
16958 # test suite 184 is for LU-2016, LU-2017
16959 test_184a() {
16960         check_swap_layouts_support
16961
16962         dir0=$DIR/$tdir/$testnum
16963         test_mkdir -p -c1 $dir0
16964         ref1=/etc/passwd
16965         ref2=/etc/group
16966         file1=$dir0/f1
16967         file2=$dir0/f2
16968         $LFS setstripe -c1 $file1
16969         cp $ref1 $file1
16970         $LFS setstripe -c2 $file2
16971         cp $ref2 $file2
16972         gen1=$($LFS getstripe -g $file1)
16973         gen2=$($LFS getstripe -g $file2)
16974
16975         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16976         gen=$($LFS getstripe -g $file1)
16977         [[ $gen1 != $gen ]] ||
16978                 "Layout generation on $file1 does not change"
16979         gen=$($LFS getstripe -g $file2)
16980         [[ $gen2 != $gen ]] ||
16981                 "Layout generation on $file2 does not change"
16982
16983         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16984         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16985
16986         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16987 }
16988 run_test 184a "Basic layout swap"
16989
16990 test_184b() {
16991         check_swap_layouts_support
16992
16993         dir0=$DIR/$tdir/$testnum
16994         mkdir -p $dir0 || error "creating dir $dir0"
16995         file1=$dir0/f1
16996         file2=$dir0/f2
16997         file3=$dir0/f3
16998         dir1=$dir0/d1
16999         dir2=$dir0/d2
17000         mkdir $dir1 $dir2
17001         $LFS setstripe -c1 $file1
17002         $LFS setstripe -c2 $file2
17003         $LFS setstripe -c1 $file3
17004         chown $RUNAS_ID $file3
17005         gen1=$($LFS getstripe -g $file1)
17006         gen2=$($LFS getstripe -g $file2)
17007
17008         $LFS swap_layouts $dir1 $dir2 &&
17009                 error "swap of directories layouts should fail"
17010         $LFS swap_layouts $dir1 $file1 &&
17011                 error "swap of directory and file layouts should fail"
17012         $RUNAS $LFS swap_layouts $file1 $file2 &&
17013                 error "swap of file we cannot write should fail"
17014         $LFS swap_layouts $file1 $file3 &&
17015                 error "swap of file with different owner should fail"
17016         /bin/true # to clear error code
17017 }
17018 run_test 184b "Forbidden layout swap (will generate errors)"
17019
17020 test_184c() {
17021         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17022         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17023         check_swap_layouts_support
17024         check_swap_layout_no_dom $DIR
17025
17026         local dir0=$DIR/$tdir/$testnum
17027         mkdir -p $dir0 || error "creating dir $dir0"
17028
17029         local ref1=$dir0/ref1
17030         local ref2=$dir0/ref2
17031         local file1=$dir0/file1
17032         local file2=$dir0/file2
17033         # create a file large enough for the concurrent test
17034         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17035         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17036         echo "ref file size: ref1($(stat -c %s $ref1))," \
17037              "ref2($(stat -c %s $ref2))"
17038
17039         cp $ref2 $file2
17040         dd if=$ref1 of=$file1 bs=16k &
17041         local DD_PID=$!
17042
17043         # Make sure dd starts to copy file, but wait at most 5 seconds
17044         local loops=0
17045         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17046
17047         $LFS swap_layouts $file1 $file2
17048         local rc=$?
17049         wait $DD_PID
17050         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17051         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17052
17053         # how many bytes copied before swapping layout
17054         local copied=$(stat -c %s $file2)
17055         local remaining=$(stat -c %s $ref1)
17056         remaining=$((remaining - copied))
17057         echo "Copied $copied bytes before swapping layout..."
17058
17059         cmp -n $copied $file1 $ref2 | grep differ &&
17060                 error "Content mismatch [0, $copied) of ref2 and file1"
17061         cmp -n $copied $file2 $ref1 ||
17062                 error "Content mismatch [0, $copied) of ref1 and file2"
17063         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17064                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17065
17066         # clean up
17067         rm -f $ref1 $ref2 $file1 $file2
17068 }
17069 run_test 184c "Concurrent write and layout swap"
17070
17071 test_184d() {
17072         check_swap_layouts_support
17073         check_swap_layout_no_dom $DIR
17074         [ -z "$(which getfattr 2>/dev/null)" ] &&
17075                 skip_env "no getfattr command"
17076
17077         local file1=$DIR/$tdir/$tfile-1
17078         local file2=$DIR/$tdir/$tfile-2
17079         local file3=$DIR/$tdir/$tfile-3
17080         local lovea1
17081         local lovea2
17082
17083         mkdir -p $DIR/$tdir
17084         touch $file1 || error "create $file1 failed"
17085         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17086                 error "create $file2 failed"
17087         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17088                 error "create $file3 failed"
17089         lovea1=$(get_layout_param $file1)
17090
17091         $LFS swap_layouts $file2 $file3 ||
17092                 error "swap $file2 $file3 layouts failed"
17093         $LFS swap_layouts $file1 $file2 ||
17094                 error "swap $file1 $file2 layouts failed"
17095
17096         lovea2=$(get_layout_param $file2)
17097         echo "$lovea1"
17098         echo "$lovea2"
17099         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17100
17101         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17102         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17103 }
17104 run_test 184d "allow stripeless layouts swap"
17105
17106 test_184e() {
17107         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17108                 skip "Need MDS version at least 2.6.94"
17109         check_swap_layouts_support
17110         check_swap_layout_no_dom $DIR
17111         [ -z "$(which getfattr 2>/dev/null)" ] &&
17112                 skip_env "no getfattr command"
17113
17114         local file1=$DIR/$tdir/$tfile-1
17115         local file2=$DIR/$tdir/$tfile-2
17116         local file3=$DIR/$tdir/$tfile-3
17117         local lovea
17118
17119         mkdir -p $DIR/$tdir
17120         touch $file1 || error "create $file1 failed"
17121         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17122                 error "create $file2 failed"
17123         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17124                 error "create $file3 failed"
17125
17126         $LFS swap_layouts $file1 $file2 ||
17127                 error "swap $file1 $file2 layouts failed"
17128
17129         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17130         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17131
17132         echo 123 > $file1 || error "Should be able to write into $file1"
17133
17134         $LFS swap_layouts $file1 $file3 ||
17135                 error "swap $file1 $file3 layouts failed"
17136
17137         echo 123 > $file1 || error "Should be able to write into $file1"
17138
17139         rm -rf $file1 $file2 $file3
17140 }
17141 run_test 184e "Recreate layout after stripeless layout swaps"
17142
17143 test_184f() {
17144         # Create a file with name longer than sizeof(struct stat) ==
17145         # 144 to see if we can get chars from the file name to appear
17146         # in the returned striping. Note that 'f' == 0x66.
17147         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17148
17149         mkdir -p $DIR/$tdir
17150         mcreate $DIR/$tdir/$file
17151         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17152                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17153         fi
17154 }
17155 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17156
17157 test_185() { # LU-2441
17158         # LU-3553 - no volatile file support in old servers
17159         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17160                 skip "Need MDS version at least 2.3.60"
17161
17162         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17163         touch $DIR/$tdir/spoo
17164         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17165         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17166                 error "cannot create/write a volatile file"
17167         [ "$FILESET" == "" ] &&
17168         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17169                 error "FID is still valid after close"
17170
17171         multiop_bg_pause $DIR/$tdir vVw4096_c
17172         local multi_pid=$!
17173
17174         local OLD_IFS=$IFS
17175         IFS=":"
17176         local fidv=($fid)
17177         IFS=$OLD_IFS
17178         # assume that the next FID for this client is sequential, since stdout
17179         # is unfortunately eaten by multiop_bg_pause
17180         local n=$((${fidv[1]} + 1))
17181         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17182         if [ "$FILESET" == "" ]; then
17183                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17184                         error "FID is missing before close"
17185         fi
17186         kill -USR1 $multi_pid
17187         # 1 second delay, so if mtime change we will see it
17188         sleep 1
17189         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17190         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17191 }
17192 run_test 185 "Volatile file support"
17193
17194 function create_check_volatile() {
17195         local idx=$1
17196         local tgt
17197
17198         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17199         local PID=$!
17200         sleep 1
17201         local FID=$(cat /tmp/${tfile}.fid)
17202         [ "$FID" == "" ] && error "can't get FID for volatile"
17203         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17204         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17205         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17206         kill -USR1 $PID
17207         wait
17208         sleep 1
17209         cancel_lru_locks mdc # flush opencache
17210         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17211         return 0
17212 }
17213
17214 test_185a(){
17215         # LU-12516 - volatile creation via .lustre
17216         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17217                 skip "Need MDS version at least 2.3.55"
17218
17219         create_check_volatile 0
17220         [ $MDSCOUNT -lt 2 ] && return 0
17221
17222         # DNE case
17223         create_check_volatile 1
17224
17225         return 0
17226 }
17227 run_test 185a "Volatile file creation in .lustre/fid/"
17228
17229 test_187a() {
17230         remote_mds_nodsh && skip "remote MDS with nodsh"
17231         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17232                 skip "Need MDS version at least 2.3.0"
17233
17234         local dir0=$DIR/$tdir/$testnum
17235         mkdir -p $dir0 || error "creating dir $dir0"
17236
17237         local file=$dir0/file1
17238         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17239         local dv1=$($LFS data_version $file)
17240         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17241         local dv2=$($LFS data_version $file)
17242         [[ $dv1 != $dv2 ]] ||
17243                 error "data version did not change on write $dv1 == $dv2"
17244
17245         # clean up
17246         rm -f $file1
17247 }
17248 run_test 187a "Test data version change"
17249
17250 test_187b() {
17251         remote_mds_nodsh && skip "remote MDS with nodsh"
17252         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17253                 skip "Need MDS version at least 2.3.0"
17254
17255         local dir0=$DIR/$tdir/$testnum
17256         mkdir -p $dir0 || error "creating dir $dir0"
17257
17258         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17259         [[ ${DV[0]} != ${DV[1]} ]] ||
17260                 error "data version did not change on write"\
17261                       " ${DV[0]} == ${DV[1]}"
17262
17263         # clean up
17264         rm -f $file1
17265 }
17266 run_test 187b "Test data version change on volatile file"
17267
17268 test_200() {
17269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17270         remote_mgs_nodsh && skip "remote MGS with nodsh"
17271         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17272
17273         local POOL=${POOL:-cea1}
17274         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17275         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17276         # Pool OST targets
17277         local first_ost=0
17278         local last_ost=$(($OSTCOUNT - 1))
17279         local ost_step=2
17280         local ost_list=$(seq $first_ost $ost_step $last_ost)
17281         local ost_range="$first_ost $last_ost $ost_step"
17282         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17283         local file_dir=$POOL_ROOT/file_tst
17284         local subdir=$test_path/subdir
17285         local rc=0
17286
17287         while : ; do
17288                 # former test_200a test_200b
17289                 pool_add $POOL                          || { rc=$? ; break; }
17290                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17291                 # former test_200c test_200d
17292                 mkdir -p $test_path
17293                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17294                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17295                 mkdir -p $subdir
17296                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17297                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17298                                                         || { rc=$? ; break; }
17299                 # former test_200e test_200f
17300                 local files=$((OSTCOUNT*3))
17301                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17302                                                         || { rc=$? ; break; }
17303                 pool_create_files $POOL $file_dir $files "$ost_list" \
17304                                                         || { rc=$? ; break; }
17305                 # former test_200g test_200h
17306                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17307                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17308
17309                 # former test_201a test_201b test_201c
17310                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17311
17312                 local f=$test_path/$tfile
17313                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17314                 pool_remove $POOL $f                    || { rc=$? ; break; }
17315                 break
17316         done
17317
17318         destroy_test_pools
17319
17320         return $rc
17321 }
17322 run_test 200 "OST pools"
17323
17324 # usage: default_attr <count | size | offset>
17325 default_attr() {
17326         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17327 }
17328
17329 # usage: check_default_stripe_attr
17330 check_default_stripe_attr() {
17331         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17332         case $1 in
17333         --stripe-count|-c)
17334                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17335         --stripe-size|-S)
17336                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17337         --stripe-index|-i)
17338                 EXPECTED=-1;;
17339         *)
17340                 error "unknown getstripe attr '$1'"
17341         esac
17342
17343         [ $ACTUAL == $EXPECTED ] ||
17344                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17345 }
17346
17347 test_204a() {
17348         test_mkdir $DIR/$tdir
17349         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17350
17351         check_default_stripe_attr --stripe-count
17352         check_default_stripe_attr --stripe-size
17353         check_default_stripe_attr --stripe-index
17354 }
17355 run_test 204a "Print default stripe attributes"
17356
17357 test_204b() {
17358         test_mkdir $DIR/$tdir
17359         $LFS setstripe --stripe-count 1 $DIR/$tdir
17360
17361         check_default_stripe_attr --stripe-size
17362         check_default_stripe_attr --stripe-index
17363 }
17364 run_test 204b "Print default stripe size and offset"
17365
17366 test_204c() {
17367         test_mkdir $DIR/$tdir
17368         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17369
17370         check_default_stripe_attr --stripe-count
17371         check_default_stripe_attr --stripe-index
17372 }
17373 run_test 204c "Print default stripe count and offset"
17374
17375 test_204d() {
17376         test_mkdir $DIR/$tdir
17377         $LFS setstripe --stripe-index 0 $DIR/$tdir
17378
17379         check_default_stripe_attr --stripe-count
17380         check_default_stripe_attr --stripe-size
17381 }
17382 run_test 204d "Print default stripe count and size"
17383
17384 test_204e() {
17385         test_mkdir $DIR/$tdir
17386         $LFS setstripe -d $DIR/$tdir
17387
17388         check_default_stripe_attr --stripe-count --raw
17389         check_default_stripe_attr --stripe-size --raw
17390         check_default_stripe_attr --stripe-index --raw
17391 }
17392 run_test 204e "Print raw stripe attributes"
17393
17394 test_204f() {
17395         test_mkdir $DIR/$tdir
17396         $LFS setstripe --stripe-count 1 $DIR/$tdir
17397
17398         check_default_stripe_attr --stripe-size --raw
17399         check_default_stripe_attr --stripe-index --raw
17400 }
17401 run_test 204f "Print raw stripe size and offset"
17402
17403 test_204g() {
17404         test_mkdir $DIR/$tdir
17405         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17406
17407         check_default_stripe_attr --stripe-count --raw
17408         check_default_stripe_attr --stripe-index --raw
17409 }
17410 run_test 204g "Print raw stripe count and offset"
17411
17412 test_204h() {
17413         test_mkdir $DIR/$tdir
17414         $LFS setstripe --stripe-index 0 $DIR/$tdir
17415
17416         check_default_stripe_attr --stripe-count --raw
17417         check_default_stripe_attr --stripe-size --raw
17418 }
17419 run_test 204h "Print raw stripe count and size"
17420
17421 # Figure out which job scheduler is being used, if any,
17422 # or use a fake one
17423 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17424         JOBENV=SLURM_JOB_ID
17425 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17426         JOBENV=LSB_JOBID
17427 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17428         JOBENV=PBS_JOBID
17429 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17430         JOBENV=LOADL_STEP_ID
17431 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17432         JOBENV=JOB_ID
17433 else
17434         $LCTL list_param jobid_name > /dev/null 2>&1
17435         if [ $? -eq 0 ]; then
17436                 JOBENV=nodelocal
17437         else
17438                 JOBENV=FAKE_JOBID
17439         fi
17440 fi
17441 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17442
17443 verify_jobstats() {
17444         local cmd=($1)
17445         shift
17446         local facets="$@"
17447
17448 # we don't really need to clear the stats for this test to work, since each
17449 # command has a unique jobid, but it makes debugging easier if needed.
17450 #       for facet in $facets; do
17451 #               local dev=$(convert_facet2label $facet)
17452 #               # clear old jobstats
17453 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17454 #       done
17455
17456         # use a new JobID for each test, or we might see an old one
17457         [ "$JOBENV" = "FAKE_JOBID" ] &&
17458                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17459
17460         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17461
17462         [ "$JOBENV" = "nodelocal" ] && {
17463                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17464                 $LCTL set_param jobid_name=$FAKE_JOBID
17465                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17466         }
17467
17468         log "Test: ${cmd[*]}"
17469         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17470
17471         if [ $JOBENV = "FAKE_JOBID" ]; then
17472                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17473         else
17474                 ${cmd[*]}
17475         fi
17476
17477         # all files are created on OST0000
17478         for facet in $facets; do
17479                 local stats="*.$(convert_facet2label $facet).job_stats"
17480
17481                 # strip out libtool wrappers for in-tree executables
17482                 if [ $(do_facet $facet lctl get_param $stats |
17483                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17484                         do_facet $facet lctl get_param $stats
17485                         error "No jobstats for $JOBVAL found on $facet::$stats"
17486                 fi
17487         done
17488 }
17489
17490 jobstats_set() {
17491         local new_jobenv=$1
17492
17493         set_persistent_param_and_check client "jobid_var" \
17494                 "$FSNAME.sys.jobid_var" $new_jobenv
17495 }
17496
17497 test_205a() { # Job stats
17498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17499         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17500                 skip "Need MDS version with at least 2.7.1"
17501         remote_mgs_nodsh && skip "remote MGS with nodsh"
17502         remote_mds_nodsh && skip "remote MDS with nodsh"
17503         remote_ost_nodsh && skip "remote OST with nodsh"
17504         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17505                 skip "Server doesn't support jobstats"
17506         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17507
17508         local old_jobenv=$($LCTL get_param -n jobid_var)
17509         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17510
17511         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17512                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17513         else
17514                 stack_trap "do_facet mgs $PERM_CMD \
17515                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17516         fi
17517         changelog_register
17518
17519         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17520                                 mdt.*.job_cleanup_interval | head -n 1)
17521         local new_interval=5
17522         do_facet $SINGLEMDS \
17523                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17524         stack_trap "do_facet $SINGLEMDS \
17525                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17526         local start=$SECONDS
17527
17528         local cmd
17529         # mkdir
17530         cmd="mkdir $DIR/$tdir"
17531         verify_jobstats "$cmd" "$SINGLEMDS"
17532         # rmdir
17533         cmd="rmdir $DIR/$tdir"
17534         verify_jobstats "$cmd" "$SINGLEMDS"
17535         # mkdir on secondary MDT
17536         if [ $MDSCOUNT -gt 1 ]; then
17537                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17538                 verify_jobstats "$cmd" "mds2"
17539         fi
17540         # mknod
17541         cmd="mknod $DIR/$tfile c 1 3"
17542         verify_jobstats "$cmd" "$SINGLEMDS"
17543         # unlink
17544         cmd="rm -f $DIR/$tfile"
17545         verify_jobstats "$cmd" "$SINGLEMDS"
17546         # create all files on OST0000 so verify_jobstats can find OST stats
17547         # open & close
17548         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17549         verify_jobstats "$cmd" "$SINGLEMDS"
17550         # setattr
17551         cmd="touch $DIR/$tfile"
17552         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17553         # write
17554         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17555         verify_jobstats "$cmd" "ost1"
17556         # read
17557         cancel_lru_locks osc
17558         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17559         verify_jobstats "$cmd" "ost1"
17560         # truncate
17561         cmd="$TRUNCATE $DIR/$tfile 0"
17562         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17563         # rename
17564         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17565         verify_jobstats "$cmd" "$SINGLEMDS"
17566         # jobstats expiry - sleep until old stats should be expired
17567         local left=$((new_interval + 5 - (SECONDS - start)))
17568         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17569                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17570                         "0" $left
17571         cmd="mkdir $DIR/$tdir.expire"
17572         verify_jobstats "$cmd" "$SINGLEMDS"
17573         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17574             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17575
17576         # Ensure that jobid are present in changelog (if supported by MDS)
17577         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17578                 changelog_dump | tail -10
17579                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17580                 [ $jobids -eq 9 ] ||
17581                         error "Wrong changelog jobid count $jobids != 9"
17582
17583                 # LU-5862
17584                 JOBENV="disable"
17585                 jobstats_set $JOBENV
17586                 touch $DIR/$tfile
17587                 changelog_dump | grep $tfile
17588                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17589                 [ $jobids -eq 0 ] ||
17590                         error "Unexpected jobids when jobid_var=$JOBENV"
17591         fi
17592
17593         # test '%j' access to environment variable - if supported
17594         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17595                 JOBENV="JOBCOMPLEX"
17596                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17597
17598                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17599         fi
17600
17601         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17602                 JOBENV="JOBCOMPLEX"
17603                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17604
17605                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17606         fi
17607
17608         # test '%j' access to per-session jobid - if supported
17609         if lctl list_param jobid_this_session > /dev/null 2>&1
17610         then
17611                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17612                 lctl set_param jobid_this_session=$USER
17613
17614                 JOBENV="JOBCOMPLEX"
17615                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17616
17617                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17618         fi
17619 }
17620 run_test 205a "Verify job stats"
17621
17622 # LU-13117, LU-13597
17623 test_205b() {
17624         job_stats="mdt.*.job_stats"
17625         $LCTL set_param $job_stats=clear
17626         # Setting jobid_var to USER might not be supported
17627         $LCTL set_param jobid_var=USER || true
17628         $LCTL set_param jobid_name="%e.%u"
17629         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17630         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17631                 grep "job_id:.*foolish" &&
17632                         error "Unexpected jobid found"
17633         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17634                 grep "open:.*min.*max.*sum" ||
17635                         error "wrong job_stats format found"
17636 }
17637 run_test 205b "Verify job stats jobid and output format"
17638
17639 # LU-13733
17640 test_205c() {
17641         $LCTL set_param llite.*.stats=0
17642         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17643         $LCTL get_param llite.*.stats
17644         $LCTL get_param llite.*.stats | grep \
17645                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17646                         error "wrong client stats format found"
17647 }
17648 run_test 205c "Verify client stats format"
17649
17650 # LU-1480, LU-1773 and LU-1657
17651 test_206() {
17652         mkdir -p $DIR/$tdir
17653         $LFS setstripe -c -1 $DIR/$tdir
17654 #define OBD_FAIL_LOV_INIT 0x1403
17655         $LCTL set_param fail_loc=0xa0001403
17656         $LCTL set_param fail_val=1
17657         touch $DIR/$tdir/$tfile || true
17658 }
17659 run_test 206 "fail lov_init_raid0() doesn't lbug"
17660
17661 test_207a() {
17662         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17663         local fsz=`stat -c %s $DIR/$tfile`
17664         cancel_lru_locks mdc
17665
17666         # do not return layout in getattr intent
17667 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17668         $LCTL set_param fail_loc=0x170
17669         local sz=`stat -c %s $DIR/$tfile`
17670
17671         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17672
17673         rm -rf $DIR/$tfile
17674 }
17675 run_test 207a "can refresh layout at glimpse"
17676
17677 test_207b() {
17678         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17679         local cksum=`md5sum $DIR/$tfile`
17680         local fsz=`stat -c %s $DIR/$tfile`
17681         cancel_lru_locks mdc
17682         cancel_lru_locks osc
17683
17684         # do not return layout in getattr intent
17685 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17686         $LCTL set_param fail_loc=0x171
17687
17688         # it will refresh layout after the file is opened but before read issues
17689         echo checksum is "$cksum"
17690         echo "$cksum" |md5sum -c --quiet || error "file differs"
17691
17692         rm -rf $DIR/$tfile
17693 }
17694 run_test 207b "can refresh layout at open"
17695
17696 test_208() {
17697         # FIXME: in this test suite, only RD lease is used. This is okay
17698         # for now as only exclusive open is supported. After generic lease
17699         # is done, this test suite should be revised. - Jinshan
17700
17701         remote_mds_nodsh && skip "remote MDS with nodsh"
17702         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17703                 skip "Need MDS version at least 2.4.52"
17704
17705         echo "==== test 1: verify get lease work"
17706         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17707
17708         echo "==== test 2: verify lease can be broken by upcoming open"
17709         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17710         local PID=$!
17711         sleep 1
17712
17713         $MULTIOP $DIR/$tfile oO_RDONLY:c
17714         kill -USR1 $PID && wait $PID || error "break lease error"
17715
17716         echo "==== test 3: verify lease can't be granted if an open already exists"
17717         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17718         local PID=$!
17719         sleep 1
17720
17721         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17722         kill -USR1 $PID && wait $PID || error "open file error"
17723
17724         echo "==== test 4: lease can sustain over recovery"
17725         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17726         PID=$!
17727         sleep 1
17728
17729         fail mds1
17730
17731         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17732
17733         echo "==== test 5: lease broken can't be regained by replay"
17734         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17735         PID=$!
17736         sleep 1
17737
17738         # open file to break lease and then recovery
17739         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17740         fail mds1
17741
17742         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17743
17744         rm -f $DIR/$tfile
17745 }
17746 run_test 208 "Exclusive open"
17747
17748 test_209() {
17749         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17750                 skip_env "must have disp_stripe"
17751
17752         touch $DIR/$tfile
17753         sync; sleep 5; sync;
17754
17755         echo 3 > /proc/sys/vm/drop_caches
17756         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17757                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17758         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17759
17760         # open/close 500 times
17761         for i in $(seq 500); do
17762                 cat $DIR/$tfile
17763         done
17764
17765         echo 3 > /proc/sys/vm/drop_caches
17766         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17767                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17768         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17769
17770         echo "before: $req_before, after: $req_after"
17771         [ $((req_after - req_before)) -ge 300 ] &&
17772                 error "open/close requests are not freed"
17773         return 0
17774 }
17775 run_test 209 "read-only open/close requests should be freed promptly"
17776
17777 test_210() {
17778         local pid
17779
17780         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17781         pid=$!
17782         sleep 1
17783
17784         $LFS getstripe $DIR/$tfile
17785         kill -USR1 $pid
17786         wait $pid || error "multiop failed"
17787
17788         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17789         pid=$!
17790         sleep 1
17791
17792         $LFS getstripe $DIR/$tfile
17793         kill -USR1 $pid
17794         wait $pid || error "multiop failed"
17795 }
17796 run_test 210 "lfs getstripe does not break leases"
17797
17798 test_212() {
17799         size=`date +%s`
17800         size=$((size % 8192 + 1))
17801         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17802         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17803         rm -f $DIR/f212 $DIR/f212.xyz
17804 }
17805 run_test 212 "Sendfile test ============================================"
17806
17807 test_213() {
17808         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17809         cancel_lru_locks osc
17810         lctl set_param fail_loc=0x8000040f
17811         # generate a read lock
17812         cat $DIR/$tfile > /dev/null
17813         # write to the file, it will try to cancel the above read lock.
17814         cat /etc/hosts >> $DIR/$tfile
17815 }
17816 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17817
17818 test_214() { # for bug 20133
17819         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17820         for (( i=0; i < 340; i++ )) ; do
17821                 touch $DIR/$tdir/d214c/a$i
17822         done
17823
17824         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17825         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17826         ls $DIR/d214c || error "ls $DIR/d214c failed"
17827         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17828         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17829 }
17830 run_test 214 "hash-indexed directory test - bug 20133"
17831
17832 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17833 create_lnet_proc_files() {
17834         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17835 }
17836
17837 # counterpart of create_lnet_proc_files
17838 remove_lnet_proc_files() {
17839         rm -f $TMP/lnet_$1.sys
17840 }
17841
17842 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17843 # 3rd arg as regexp for body
17844 check_lnet_proc_stats() {
17845         local l=$(cat "$TMP/lnet_$1" |wc -l)
17846         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17847
17848         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17849 }
17850
17851 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17852 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17853 # optional and can be regexp for 2nd line (lnet.routes case)
17854 check_lnet_proc_entry() {
17855         local blp=2          # blp stands for 'position of 1st line of body'
17856         [ -z "$5" ] || blp=3 # lnet.routes case
17857
17858         local l=$(cat "$TMP/lnet_$1" |wc -l)
17859         # subtracting one from $blp because the body can be empty
17860         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17861
17862         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17863                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17864
17865         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17866                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17867
17868         # bail out if any unexpected line happened
17869         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17870         [ "$?" != 0 ] || error "$2 misformatted"
17871 }
17872
17873 test_215() { # for bugs 18102, 21079, 21517
17874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17875
17876         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17877         local P='[1-9][0-9]*'           # positive numeric
17878         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17879         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17880         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17881         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17882
17883         local L1 # regexp for 1st line
17884         local L2 # regexp for 2nd line (optional)
17885         local BR # regexp for the rest (body)
17886
17887         # lnet.stats should look as 11 space-separated non-negative numerics
17888         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17889         create_lnet_proc_files "stats"
17890         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17891         remove_lnet_proc_files "stats"
17892
17893         # lnet.routes should look like this:
17894         # Routing disabled/enabled
17895         # net hops priority state router
17896         # where net is a string like tcp0, hops > 0, priority >= 0,
17897         # state is up/down,
17898         # router is a string like 192.168.1.1@tcp2
17899         L1="^Routing (disabled|enabled)$"
17900         L2="^net +hops +priority +state +router$"
17901         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17902         create_lnet_proc_files "routes"
17903         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17904         remove_lnet_proc_files "routes"
17905
17906         # lnet.routers should look like this:
17907         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17908         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17909         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17910         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17911         L1="^ref +rtr_ref +alive +router$"
17912         BR="^$P +$P +(up|down) +$NID$"
17913         create_lnet_proc_files "routers"
17914         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17915         remove_lnet_proc_files "routers"
17916
17917         # lnet.peers should look like this:
17918         # nid refs state last max rtr min tx min queue
17919         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17920         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17921         # numeric (0 or >0 or <0), queue >= 0.
17922         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17923         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17924         create_lnet_proc_files "peers"
17925         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17926         remove_lnet_proc_files "peers"
17927
17928         # lnet.buffers  should look like this:
17929         # pages count credits min
17930         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17931         L1="^pages +count +credits +min$"
17932         BR="^ +$N +$N +$I +$I$"
17933         create_lnet_proc_files "buffers"
17934         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17935         remove_lnet_proc_files "buffers"
17936
17937         # lnet.nis should look like this:
17938         # nid status alive refs peer rtr max tx min
17939         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17940         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17941         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17942         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17943         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17944         create_lnet_proc_files "nis"
17945         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17946         remove_lnet_proc_files "nis"
17947
17948         # can we successfully write to lnet.stats?
17949         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17950 }
17951 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17952
17953 test_216() { # bug 20317
17954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17955         remote_ost_nodsh && skip "remote OST with nodsh"
17956
17957         local node
17958         local facets=$(get_facets OST)
17959         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17960
17961         save_lustre_params client "osc.*.contention_seconds" > $p
17962         save_lustre_params $facets \
17963                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17964         save_lustre_params $facets \
17965                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17966         save_lustre_params $facets \
17967                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17968         clear_stats osc.*.osc_stats
17969
17970         # agressive lockless i/o settings
17971         do_nodes $(comma_list $(osts_nodes)) \
17972                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17973                         ldlm.namespaces.filter-*.contended_locks=0 \
17974                         ldlm.namespaces.filter-*.contention_seconds=60"
17975         lctl set_param -n osc.*.contention_seconds=60
17976
17977         $DIRECTIO write $DIR/$tfile 0 10 4096
17978         $CHECKSTAT -s 40960 $DIR/$tfile
17979
17980         # disable lockless i/o
17981         do_nodes $(comma_list $(osts_nodes)) \
17982                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17983                         ldlm.namespaces.filter-*.contended_locks=32 \
17984                         ldlm.namespaces.filter-*.contention_seconds=0"
17985         lctl set_param -n osc.*.contention_seconds=0
17986         clear_stats osc.*.osc_stats
17987
17988         dd if=/dev/zero of=$DIR/$tfile count=0
17989         $CHECKSTAT -s 0 $DIR/$tfile
17990
17991         restore_lustre_params <$p
17992         rm -f $p
17993         rm $DIR/$tfile
17994 }
17995 run_test 216 "check lockless direct write updates file size and kms correctly"
17996
17997 test_217() { # bug 22430
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999
18000         local node
18001         local nid
18002
18003         for node in $(nodes_list); do
18004                 nid=$(host_nids_address $node $NETTYPE)
18005                 if [[ $nid = *-* ]] ; then
18006                         echo "lctl ping $(h2nettype $nid)"
18007                         lctl ping $(h2nettype $nid)
18008                 else
18009                         echo "skipping $node (no hyphen detected)"
18010                 fi
18011         done
18012 }
18013 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18014
18015 test_218() {
18016        # do directio so as not to populate the page cache
18017        log "creating a 10 Mb file"
18018        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18019        log "starting reads"
18020        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18021        log "truncating the file"
18022        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18023        log "killing dd"
18024        kill %+ || true # reads might have finished
18025        echo "wait until dd is finished"
18026        wait
18027        log "removing the temporary file"
18028        rm -rf $DIR/$tfile || error "tmp file removal failed"
18029 }
18030 run_test 218 "parallel read and truncate should not deadlock"
18031
18032 test_219() {
18033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18034
18035         # write one partial page
18036         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18037         # set no grant so vvp_io_commit_write will do sync write
18038         $LCTL set_param fail_loc=0x411
18039         # write a full page at the end of file
18040         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18041
18042         $LCTL set_param fail_loc=0
18043         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18044         $LCTL set_param fail_loc=0x411
18045         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18046
18047         # LU-4201
18048         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18049         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18050 }
18051 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18052
18053 test_220() { #LU-325
18054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18055         remote_ost_nodsh && skip "remote OST with nodsh"
18056         remote_mds_nodsh && skip "remote MDS with nodsh"
18057         remote_mgs_nodsh && skip "remote MGS with nodsh"
18058
18059         local OSTIDX=0
18060
18061         # create on MDT0000 so the last_id and next_id are correct
18062         mkdir $DIR/$tdir
18063         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18064         OST=${OST%_UUID}
18065
18066         # on the mdt's osc
18067         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18068         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18069                         osp.$mdtosc_proc1.prealloc_last_id)
18070         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18071                         osp.$mdtosc_proc1.prealloc_next_id)
18072
18073         $LFS df -i
18074
18075         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18076         #define OBD_FAIL_OST_ENOINO              0x229
18077         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18078         create_pool $FSNAME.$TESTNAME || return 1
18079         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18080
18081         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18082
18083         MDSOBJS=$((last_id - next_id))
18084         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18085
18086         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18087         echo "OST still has $count kbytes free"
18088
18089         echo "create $MDSOBJS files @next_id..."
18090         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18091
18092         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18093                         osp.$mdtosc_proc1.prealloc_last_id)
18094         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18095                         osp.$mdtosc_proc1.prealloc_next_id)
18096
18097         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18098         $LFS df -i
18099
18100         echo "cleanup..."
18101
18102         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18103         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18104
18105         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18106                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18107         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18108                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18109         echo "unlink $MDSOBJS files @$next_id..."
18110         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18111 }
18112 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18113
18114 test_221() {
18115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18116
18117         dd if=`which date` of=$MOUNT/date oflag=sync
18118         chmod +x $MOUNT/date
18119
18120         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18121         $LCTL set_param fail_loc=0x80001401
18122
18123         $MOUNT/date > /dev/null
18124         rm -f $MOUNT/date
18125 }
18126 run_test 221 "make sure fault and truncate race to not cause OOM"
18127
18128 test_222a () {
18129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18130
18131         rm -rf $DIR/$tdir
18132         test_mkdir $DIR/$tdir
18133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18134         createmany -o $DIR/$tdir/$tfile 10
18135         cancel_lru_locks mdc
18136         cancel_lru_locks osc
18137         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18138         $LCTL set_param fail_loc=0x31a
18139         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18140         $LCTL set_param fail_loc=0
18141         rm -r $DIR/$tdir
18142 }
18143 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18144
18145 test_222b () {
18146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18147
18148         rm -rf $DIR/$tdir
18149         test_mkdir $DIR/$tdir
18150         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18151         createmany -o $DIR/$tdir/$tfile 10
18152         cancel_lru_locks mdc
18153         cancel_lru_locks osc
18154         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18155         $LCTL set_param fail_loc=0x31a
18156         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18157         $LCTL set_param fail_loc=0
18158 }
18159 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18160
18161 test_223 () {
18162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18163
18164         rm -rf $DIR/$tdir
18165         test_mkdir $DIR/$tdir
18166         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18167         createmany -o $DIR/$tdir/$tfile 10
18168         cancel_lru_locks mdc
18169         cancel_lru_locks osc
18170         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18171         $LCTL set_param fail_loc=0x31b
18172         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18173         $LCTL set_param fail_loc=0
18174         rm -r $DIR/$tdir
18175 }
18176 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18177
18178 test_224a() { # LU-1039, MRP-303
18179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18180
18181         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18182         $LCTL set_param fail_loc=0x508
18183         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18184         $LCTL set_param fail_loc=0
18185         df $DIR
18186 }
18187 run_test 224a "Don't panic on bulk IO failure"
18188
18189 test_224b() { # LU-1039, MRP-303
18190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18191
18192         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18193         cancel_lru_locks osc
18194         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18195         $LCTL set_param fail_loc=0x515
18196         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18197         $LCTL set_param fail_loc=0
18198         df $DIR
18199 }
18200 run_test 224b "Don't panic on bulk IO failure"
18201
18202 test_224c() { # LU-6441
18203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18204         remote_mds_nodsh && skip "remote MDS with nodsh"
18205
18206         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18207         save_writethrough $p
18208         set_cache writethrough on
18209
18210         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18211         local at_max=$($LCTL get_param -n at_max)
18212         local timeout=$($LCTL get_param -n timeout)
18213         local test_at="at_max"
18214         local param_at="$FSNAME.sys.at_max"
18215         local test_timeout="timeout"
18216         local param_timeout="$FSNAME.sys.timeout"
18217
18218         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18219
18220         set_persistent_param_and_check client "$test_at" "$param_at" 0
18221         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18222
18223         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18224         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18225         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18226         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18227         sync
18228         do_facet ost1 "$LCTL set_param fail_loc=0"
18229
18230         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18231         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18232                 $timeout
18233
18234         $LCTL set_param -n $pages_per_rpc
18235         restore_lustre_params < $p
18236         rm -f $p
18237 }
18238 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18239
18240 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18241 test_225a () {
18242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18243         if [ -z ${MDSSURVEY} ]; then
18244                 skip_env "mds-survey not found"
18245         fi
18246         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18247                 skip "Need MDS version at least 2.2.51"
18248
18249         local mds=$(facet_host $SINGLEMDS)
18250         local target=$(do_nodes $mds 'lctl dl' |
18251                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18252
18253         local cmd1="file_count=1000 thrhi=4"
18254         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18255         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18256         local cmd="$cmd1 $cmd2 $cmd3"
18257
18258         rm -f ${TMP}/mds_survey*
18259         echo + $cmd
18260         eval $cmd || error "mds-survey with zero-stripe failed"
18261         cat ${TMP}/mds_survey*
18262         rm -f ${TMP}/mds_survey*
18263 }
18264 run_test 225a "Metadata survey sanity with zero-stripe"
18265
18266 test_225b () {
18267         if [ -z ${MDSSURVEY} ]; then
18268                 skip_env "mds-survey not found"
18269         fi
18270         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18271                 skip "Need MDS version at least 2.2.51"
18272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18273         remote_mds_nodsh && skip "remote MDS with nodsh"
18274         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18275                 skip_env "Need to mount OST to test"
18276         fi
18277
18278         local mds=$(facet_host $SINGLEMDS)
18279         local target=$(do_nodes $mds 'lctl dl' |
18280                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18281
18282         local cmd1="file_count=1000 thrhi=4"
18283         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18284         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18285         local cmd="$cmd1 $cmd2 $cmd3"
18286
18287         rm -f ${TMP}/mds_survey*
18288         echo + $cmd
18289         eval $cmd || error "mds-survey with stripe_count failed"
18290         cat ${TMP}/mds_survey*
18291         rm -f ${TMP}/mds_survey*
18292 }
18293 run_test 225b "Metadata survey sanity with stripe_count = 1"
18294
18295 mcreate_path2fid () {
18296         local mode=$1
18297         local major=$2
18298         local minor=$3
18299         local name=$4
18300         local desc=$5
18301         local path=$DIR/$tdir/$name
18302         local fid
18303         local rc
18304         local fid_path
18305
18306         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18307                 error "cannot create $desc"
18308
18309         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18310         rc=$?
18311         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18312
18313         fid_path=$($LFS fid2path $MOUNT $fid)
18314         rc=$?
18315         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18316
18317         [ "$path" == "$fid_path" ] ||
18318                 error "fid2path returned $fid_path, expected $path"
18319
18320         echo "pass with $path and $fid"
18321 }
18322
18323 test_226a () {
18324         rm -rf $DIR/$tdir
18325         mkdir -p $DIR/$tdir
18326
18327         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18328         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18329         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18330         mcreate_path2fid 0040666 0 0 dir "directory"
18331         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18332         mcreate_path2fid 0100666 0 0 file "regular file"
18333         mcreate_path2fid 0120666 0 0 link "symbolic link"
18334         mcreate_path2fid 0140666 0 0 sock "socket"
18335 }
18336 run_test 226a "call path2fid and fid2path on files of all type"
18337
18338 test_226b () {
18339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18340
18341         local MDTIDX=1
18342
18343         rm -rf $DIR/$tdir
18344         mkdir -p $DIR/$tdir
18345         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18346                 error "create remote directory failed"
18347         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18348         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18349                                 "character special file (null)"
18350         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18351                                 "character special file (no device)"
18352         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18353         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18354                                 "block special file (loop)"
18355         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18356         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18357         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18358 }
18359 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18360
18361 test_226c () {
18362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18363         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18364                 skip "Need MDS version at least 2.13.55"
18365
18366         local submnt=/mnt/submnt
18367         local srcfile=/etc/passwd
18368         local dstfile=$submnt/passwd
18369         local path
18370         local fid
18371
18372         rm -rf $DIR/$tdir
18373         rm -rf $submnt
18374         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18375                 error "create remote directory failed"
18376         mkdir -p $submnt || error "create $submnt failed"
18377         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18378                 error "mount $submnt failed"
18379         stack_trap "umount $submnt" EXIT
18380
18381         cp $srcfile $dstfile
18382         fid=$($LFS path2fid $dstfile)
18383         path=$($LFS fid2path $submnt "$fid")
18384         [ "$path" = "$dstfile" ] ||
18385                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18386 }
18387 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18388
18389 # LU-1299 Executing or running ldd on a truncated executable does not
18390 # cause an out-of-memory condition.
18391 test_227() {
18392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18393         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18394
18395         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18396         chmod +x $MOUNT/date
18397
18398         $MOUNT/date > /dev/null
18399         ldd $MOUNT/date > /dev/null
18400         rm -f $MOUNT/date
18401 }
18402 run_test 227 "running truncated executable does not cause OOM"
18403
18404 # LU-1512 try to reuse idle OI blocks
18405 test_228a() {
18406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18407         remote_mds_nodsh && skip "remote MDS with nodsh"
18408         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18409
18410         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18411         local myDIR=$DIR/$tdir
18412
18413         mkdir -p $myDIR
18414         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18415         $LCTL set_param fail_loc=0x80001002
18416         createmany -o $myDIR/t- 10000
18417         $LCTL set_param fail_loc=0
18418         # The guard is current the largest FID holder
18419         touch $myDIR/guard
18420         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18421                     tr -d '[')
18422         local IDX=$(($SEQ % 64))
18423
18424         do_facet $SINGLEMDS sync
18425         # Make sure journal flushed.
18426         sleep 6
18427         local blk1=$(do_facet $SINGLEMDS \
18428                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18429                      grep Blockcount | awk '{print $4}')
18430
18431         # Remove old files, some OI blocks will become idle.
18432         unlinkmany $myDIR/t- 10000
18433         # Create new files, idle OI blocks should be reused.
18434         createmany -o $myDIR/t- 2000
18435         do_facet $SINGLEMDS sync
18436         # Make sure journal flushed.
18437         sleep 6
18438         local blk2=$(do_facet $SINGLEMDS \
18439                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18440                      grep Blockcount | awk '{print $4}')
18441
18442         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18443 }
18444 run_test 228a "try to reuse idle OI blocks"
18445
18446 test_228b() {
18447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18448         remote_mds_nodsh && skip "remote MDS with nodsh"
18449         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18450
18451         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18452         local myDIR=$DIR/$tdir
18453
18454         mkdir -p $myDIR
18455         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18456         $LCTL set_param fail_loc=0x80001002
18457         createmany -o $myDIR/t- 10000
18458         $LCTL set_param fail_loc=0
18459         # The guard is current the largest FID holder
18460         touch $myDIR/guard
18461         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18462                     tr -d '[')
18463         local IDX=$(($SEQ % 64))
18464
18465         do_facet $SINGLEMDS sync
18466         # Make sure journal flushed.
18467         sleep 6
18468         local blk1=$(do_facet $SINGLEMDS \
18469                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18470                      grep Blockcount | awk '{print $4}')
18471
18472         # Remove old files, some OI blocks will become idle.
18473         unlinkmany $myDIR/t- 10000
18474
18475         # stop the MDT
18476         stop $SINGLEMDS || error "Fail to stop MDT."
18477         # remount the MDT
18478         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18479
18480         df $MOUNT || error "Fail to df."
18481         # Create new files, idle OI blocks should be reused.
18482         createmany -o $myDIR/t- 2000
18483         do_facet $SINGLEMDS sync
18484         # Make sure journal flushed.
18485         sleep 6
18486         local blk2=$(do_facet $SINGLEMDS \
18487                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18488                      grep Blockcount | awk '{print $4}')
18489
18490         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18491 }
18492 run_test 228b "idle OI blocks can be reused after MDT restart"
18493
18494 #LU-1881
18495 test_228c() {
18496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18497         remote_mds_nodsh && skip "remote MDS with nodsh"
18498         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18499
18500         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18501         local myDIR=$DIR/$tdir
18502
18503         mkdir -p $myDIR
18504         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18505         $LCTL set_param fail_loc=0x80001002
18506         # 20000 files can guarantee there are index nodes in the OI file
18507         createmany -o $myDIR/t- 20000
18508         $LCTL set_param fail_loc=0
18509         # The guard is current the largest FID holder
18510         touch $myDIR/guard
18511         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18512                     tr -d '[')
18513         local IDX=$(($SEQ % 64))
18514
18515         do_facet $SINGLEMDS sync
18516         # Make sure journal flushed.
18517         sleep 6
18518         local blk1=$(do_facet $SINGLEMDS \
18519                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18520                      grep Blockcount | awk '{print $4}')
18521
18522         # Remove old files, some OI blocks will become idle.
18523         unlinkmany $myDIR/t- 20000
18524         rm -f $myDIR/guard
18525         # The OI file should become empty now
18526
18527         # Create new files, idle OI blocks should be reused.
18528         createmany -o $myDIR/t- 2000
18529         do_facet $SINGLEMDS sync
18530         # Make sure journal flushed.
18531         sleep 6
18532         local blk2=$(do_facet $SINGLEMDS \
18533                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18534                      grep Blockcount | awk '{print $4}')
18535
18536         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18537 }
18538 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18539
18540 test_229() { # LU-2482, LU-3448
18541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18542         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18543         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18544                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18545
18546         rm -f $DIR/$tfile
18547
18548         # Create a file with a released layout and stripe count 2.
18549         $MULTIOP $DIR/$tfile H2c ||
18550                 error "failed to create file with released layout"
18551
18552         $LFS getstripe -v $DIR/$tfile
18553
18554         local pattern=$($LFS getstripe -L $DIR/$tfile)
18555         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18556
18557         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18558                 error "getstripe"
18559         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18560         stat $DIR/$tfile || error "failed to stat released file"
18561
18562         chown $RUNAS_ID $DIR/$tfile ||
18563                 error "chown $RUNAS_ID $DIR/$tfile failed"
18564
18565         chgrp $RUNAS_ID $DIR/$tfile ||
18566                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18567
18568         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18569         rm $DIR/$tfile || error "failed to remove released file"
18570 }
18571 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18572
18573 test_230a() {
18574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18576         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18577                 skip "Need MDS version at least 2.11.52"
18578
18579         local MDTIDX=1
18580
18581         test_mkdir $DIR/$tdir
18582         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18583         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18584         [ $mdt_idx -ne 0 ] &&
18585                 error "create local directory on wrong MDT $mdt_idx"
18586
18587         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18588                         error "create remote directory failed"
18589         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18590         [ $mdt_idx -ne $MDTIDX ] &&
18591                 error "create remote directory on wrong MDT $mdt_idx"
18592
18593         createmany -o $DIR/$tdir/test_230/t- 10 ||
18594                 error "create files on remote directory failed"
18595         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18596         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18597         rm -r $DIR/$tdir || error "unlink remote directory failed"
18598 }
18599 run_test 230a "Create remote directory and files under the remote directory"
18600
18601 test_230b() {
18602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18603         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18604         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18605                 skip "Need MDS version at least 2.11.52"
18606
18607         local MDTIDX=1
18608         local mdt_index
18609         local i
18610         local file
18611         local pid
18612         local stripe_count
18613         local migrate_dir=$DIR/$tdir/migrate_dir
18614         local other_dir=$DIR/$tdir/other_dir
18615
18616         test_mkdir $DIR/$tdir
18617         test_mkdir -i0 -c1 $migrate_dir
18618         test_mkdir -i0 -c1 $other_dir
18619         for ((i=0; i<10; i++)); do
18620                 mkdir -p $migrate_dir/dir_${i}
18621                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18622                         error "create files under remote dir failed $i"
18623         done
18624
18625         cp /etc/passwd $migrate_dir/$tfile
18626         cp /etc/passwd $other_dir/$tfile
18627         chattr +SAD $migrate_dir
18628         chattr +SAD $migrate_dir/$tfile
18629
18630         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18631         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18632         local old_dir_mode=$(stat -c%f $migrate_dir)
18633         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18634
18635         mkdir -p $migrate_dir/dir_default_stripe2
18636         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18637         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18638
18639         mkdir -p $other_dir
18640         ln $migrate_dir/$tfile $other_dir/luna
18641         ln $migrate_dir/$tfile $migrate_dir/sofia
18642         ln $other_dir/$tfile $migrate_dir/david
18643         ln -s $migrate_dir/$tfile $other_dir/zachary
18644         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18645         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18646
18647         local len
18648         local lnktgt
18649
18650         # inline symlink
18651         for len in 58 59 60; do
18652                 lnktgt=$(str_repeat 'l' $len)
18653                 touch $migrate_dir/$lnktgt
18654                 ln -s $lnktgt $migrate_dir/${len}char_ln
18655         done
18656
18657         # PATH_MAX
18658         for len in 4094 4095; do
18659                 lnktgt=$(str_repeat 'l' $len)
18660                 ln -s $lnktgt $migrate_dir/${len}char_ln
18661         done
18662
18663         # NAME_MAX
18664         for len in 254 255; do
18665                 touch $migrate_dir/$(str_repeat 'l' $len)
18666         done
18667
18668         $LFS migrate -m $MDTIDX $migrate_dir ||
18669                 error "fails on migrating remote dir to MDT1"
18670
18671         echo "migratate to MDT1, then checking.."
18672         for ((i = 0; i < 10; i++)); do
18673                 for file in $(find $migrate_dir/dir_${i}); do
18674                         mdt_index=$($LFS getstripe -m $file)
18675                         # broken symlink getstripe will fail
18676                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18677                                 error "$file is not on MDT${MDTIDX}"
18678                 done
18679         done
18680
18681         # the multiple link file should still in MDT0
18682         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18683         [ $mdt_index == 0 ] ||
18684                 error "$file is not on MDT${MDTIDX}"
18685
18686         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18687         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18688                 error " expect $old_dir_flag get $new_dir_flag"
18689
18690         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18691         [ "$old_file_flag" = "$new_file_flag" ] ||
18692                 error " expect $old_file_flag get $new_file_flag"
18693
18694         local new_dir_mode=$(stat -c%f $migrate_dir)
18695         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18696                 error "expect mode $old_dir_mode get $new_dir_mode"
18697
18698         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18699         [ "$old_file_mode" = "$new_file_mode" ] ||
18700                 error "expect mode $old_file_mode get $new_file_mode"
18701
18702         diff /etc/passwd $migrate_dir/$tfile ||
18703                 error "$tfile different after migration"
18704
18705         diff /etc/passwd $other_dir/luna ||
18706                 error "luna different after migration"
18707
18708         diff /etc/passwd $migrate_dir/sofia ||
18709                 error "sofia different after migration"
18710
18711         diff /etc/passwd $migrate_dir/david ||
18712                 error "david different after migration"
18713
18714         diff /etc/passwd $other_dir/zachary ||
18715                 error "zachary different after migration"
18716
18717         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18718                 error "${tfile}_ln different after migration"
18719
18720         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18721                 error "${tfile}_ln_other different after migration"
18722
18723         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18724         [ $stripe_count = 2 ] ||
18725                 error "dir strpe_count $d != 2 after migration."
18726
18727         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18728         [ $stripe_count = 2 ] ||
18729                 error "file strpe_count $d != 2 after migration."
18730
18731         #migrate back to MDT0
18732         MDTIDX=0
18733
18734         $LFS migrate -m $MDTIDX $migrate_dir ||
18735                 error "fails on migrating remote dir to MDT0"
18736
18737         echo "migrate back to MDT0, checking.."
18738         for file in $(find $migrate_dir); do
18739                 mdt_index=$($LFS getstripe -m $file)
18740                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18741                         error "$file is not on MDT${MDTIDX}"
18742         done
18743
18744         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18745         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18746                 error " expect $old_dir_flag get $new_dir_flag"
18747
18748         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18749         [ "$old_file_flag" = "$new_file_flag" ] ||
18750                 error " expect $old_file_flag get $new_file_flag"
18751
18752         local new_dir_mode=$(stat -c%f $migrate_dir)
18753         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18754                 error "expect mode $old_dir_mode get $new_dir_mode"
18755
18756         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18757         [ "$old_file_mode" = "$new_file_mode" ] ||
18758                 error "expect mode $old_file_mode get $new_file_mode"
18759
18760         diff /etc/passwd ${migrate_dir}/$tfile ||
18761                 error "$tfile different after migration"
18762
18763         diff /etc/passwd ${other_dir}/luna ||
18764                 error "luna different after migration"
18765
18766         diff /etc/passwd ${migrate_dir}/sofia ||
18767                 error "sofia different after migration"
18768
18769         diff /etc/passwd ${other_dir}/zachary ||
18770                 error "zachary different after migration"
18771
18772         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18773                 error "${tfile}_ln different after migration"
18774
18775         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18776                 error "${tfile}_ln_other different after migration"
18777
18778         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18779         [ $stripe_count = 2 ] ||
18780                 error "dir strpe_count $d != 2 after migration."
18781
18782         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18783         [ $stripe_count = 2 ] ||
18784                 error "file strpe_count $d != 2 after migration."
18785
18786         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18787 }
18788 run_test 230b "migrate directory"
18789
18790 test_230c() {
18791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18793         remote_mds_nodsh && skip "remote MDS with nodsh"
18794         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18795                 skip "Need MDS version at least 2.11.52"
18796
18797         local MDTIDX=1
18798         local total=3
18799         local mdt_index
18800         local file
18801         local migrate_dir=$DIR/$tdir/migrate_dir
18802
18803         #If migrating directory fails in the middle, all entries of
18804         #the directory is still accessiable.
18805         test_mkdir $DIR/$tdir
18806         test_mkdir -i0 -c1 $migrate_dir
18807         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18808         stat $migrate_dir
18809         createmany -o $migrate_dir/f $total ||
18810                 error "create files under ${migrate_dir} failed"
18811
18812         # fail after migrating top dir, and this will fail only once, so the
18813         # first sub file migration will fail (currently f3), others succeed.
18814         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18815         do_facet mds1 lctl set_param fail_loc=0x1801
18816         local t=$(ls $migrate_dir | wc -l)
18817         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18818                 error "migrate should fail"
18819         local u=$(ls $migrate_dir | wc -l)
18820         [ "$u" == "$t" ] || error "$u != $t during migration"
18821
18822         # add new dir/file should succeed
18823         mkdir $migrate_dir/dir ||
18824                 error "mkdir failed under migrating directory"
18825         touch $migrate_dir/file ||
18826                 error "create file failed under migrating directory"
18827
18828         # add file with existing name should fail
18829         for file in $migrate_dir/f*; do
18830                 stat $file > /dev/null || error "stat $file failed"
18831                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18832                         error "open(O_CREAT|O_EXCL) $file should fail"
18833                 $MULTIOP $file m && error "create $file should fail"
18834                 touch $DIR/$tdir/remote_dir/$tfile ||
18835                         error "touch $tfile failed"
18836                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18837                         error "link $file should fail"
18838                 mdt_index=$($LFS getstripe -m $file)
18839                 if [ $mdt_index == 0 ]; then
18840                         # file failed to migrate is not allowed to rename to
18841                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18842                                 error "rename to $file should fail"
18843                 else
18844                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18845                                 error "rename to $file failed"
18846                 fi
18847                 echo hello >> $file || error "write $file failed"
18848         done
18849
18850         # resume migration with different options should fail
18851         $LFS migrate -m 0 $migrate_dir &&
18852                 error "migrate -m 0 $migrate_dir should fail"
18853
18854         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18855                 error "migrate -c 2 $migrate_dir should fail"
18856
18857         # resume migration should succeed
18858         $LFS migrate -m $MDTIDX $migrate_dir ||
18859                 error "migrate $migrate_dir failed"
18860
18861         echo "Finish migration, then checking.."
18862         for file in $(find $migrate_dir); do
18863                 mdt_index=$($LFS getstripe -m $file)
18864                 [ $mdt_index == $MDTIDX ] ||
18865                         error "$file is not on MDT${MDTIDX}"
18866         done
18867
18868         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18869 }
18870 run_test 230c "check directory accessiblity if migration failed"
18871
18872 test_230d() {
18873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18875         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18876                 skip "Need MDS version at least 2.11.52"
18877         # LU-11235
18878         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18879
18880         local migrate_dir=$DIR/$tdir/migrate_dir
18881         local old_index
18882         local new_index
18883         local old_count
18884         local new_count
18885         local new_hash
18886         local mdt_index
18887         local i
18888         local j
18889
18890         old_index=$((RANDOM % MDSCOUNT))
18891         old_count=$((MDSCOUNT - old_index))
18892         new_index=$((RANDOM % MDSCOUNT))
18893         new_count=$((MDSCOUNT - new_index))
18894         new_hash=1 # for all_char
18895
18896         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18897         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18898
18899         test_mkdir $DIR/$tdir
18900         test_mkdir -i $old_index -c $old_count $migrate_dir
18901
18902         for ((i=0; i<100; i++)); do
18903                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18904                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18905                         error "create files under remote dir failed $i"
18906         done
18907
18908         echo -n "Migrate from MDT$old_index "
18909         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18910         echo -n "to MDT$new_index"
18911         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18912         echo
18913
18914         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18915         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18916                 error "migrate remote dir error"
18917
18918         echo "Finish migration, then checking.."
18919         for file in $(find $migrate_dir); do
18920                 mdt_index=$($LFS getstripe -m $file)
18921                 if [ $mdt_index -lt $new_index ] ||
18922                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18923                         error "$file is on MDT$mdt_index"
18924                 fi
18925         done
18926
18927         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18928 }
18929 run_test 230d "check migrate big directory"
18930
18931 test_230e() {
18932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18934         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18935                 skip "Need MDS version at least 2.11.52"
18936
18937         local i
18938         local j
18939         local a_fid
18940         local b_fid
18941
18942         mkdir -p $DIR/$tdir
18943         mkdir $DIR/$tdir/migrate_dir
18944         mkdir $DIR/$tdir/other_dir
18945         touch $DIR/$tdir/migrate_dir/a
18946         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18947         ls $DIR/$tdir/other_dir
18948
18949         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18950                 error "migrate dir fails"
18951
18952         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18953         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18954
18955         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18956         [ $mdt_index == 0 ] || error "a is not on MDT0"
18957
18958         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18959                 error "migrate dir fails"
18960
18961         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18962         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18963
18964         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18965         [ $mdt_index == 1 ] || error "a is not on MDT1"
18966
18967         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18968         [ $mdt_index == 1 ] || error "b is not on MDT1"
18969
18970         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18971         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18972
18973         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18974
18975         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18976 }
18977 run_test 230e "migrate mulitple local link files"
18978
18979 test_230f() {
18980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18982         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18983                 skip "Need MDS version at least 2.11.52"
18984
18985         local a_fid
18986         local ln_fid
18987
18988         mkdir -p $DIR/$tdir
18989         mkdir $DIR/$tdir/migrate_dir
18990         $LFS mkdir -i1 $DIR/$tdir/other_dir
18991         touch $DIR/$tdir/migrate_dir/a
18992         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18993         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18994         ls $DIR/$tdir/other_dir
18995
18996         # a should be migrated to MDT1, since no other links on MDT0
18997         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18998                 error "#1 migrate dir fails"
18999         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19000         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19001         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19002         [ $mdt_index == 1 ] || error "a is not on MDT1"
19003
19004         # a should stay on MDT1, because it is a mulitple link file
19005         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19006                 error "#2 migrate dir fails"
19007         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19008         [ $mdt_index == 1 ] || error "a is not on MDT1"
19009
19010         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19011                 error "#3 migrate dir fails"
19012
19013         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19014         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19015         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19016
19017         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19018         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19019
19020         # a should be migrated to MDT0, since no other links on MDT1
19021         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19022                 error "#4 migrate dir fails"
19023         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19024         [ $mdt_index == 0 ] || error "a is not on MDT0"
19025
19026         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19027 }
19028 run_test 230f "migrate mulitple remote link files"
19029
19030 test_230g() {
19031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19033         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19034                 skip "Need MDS version at least 2.11.52"
19035
19036         mkdir -p $DIR/$tdir/migrate_dir
19037
19038         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19039                 error "migrating dir to non-exist MDT succeeds"
19040         true
19041 }
19042 run_test 230g "migrate dir to non-exist MDT"
19043
19044 test_230h() {
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19047         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19048                 skip "Need MDS version at least 2.11.52"
19049
19050         local mdt_index
19051
19052         mkdir -p $DIR/$tdir/migrate_dir
19053
19054         $LFS migrate -m1 $DIR &&
19055                 error "migrating mountpoint1 should fail"
19056
19057         $LFS migrate -m1 $DIR/$tdir/.. &&
19058                 error "migrating mountpoint2 should fail"
19059
19060         # same as mv
19061         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19062                 error "migrating $tdir/migrate_dir/.. should fail"
19063
19064         true
19065 }
19066 run_test 230h "migrate .. and root"
19067
19068 test_230i() {
19069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19071         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19072                 skip "Need MDS version at least 2.11.52"
19073
19074         mkdir -p $DIR/$tdir/migrate_dir
19075
19076         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19077                 error "migration fails with a tailing slash"
19078
19079         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19080                 error "migration fails with two tailing slashes"
19081 }
19082 run_test 230i "lfs migrate -m tolerates trailing slashes"
19083
19084 test_230j() {
19085         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19086         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19087                 skip "Need MDS version at least 2.11.52"
19088
19089         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19090         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19091                 error "create $tfile failed"
19092         cat /etc/passwd > $DIR/$tdir/$tfile
19093
19094         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19095
19096         cmp /etc/passwd $DIR/$tdir/$tfile ||
19097                 error "DoM file mismatch after migration"
19098 }
19099 run_test 230j "DoM file data not changed after dir migration"
19100
19101 test_230k() {
19102         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19103         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19104                 skip "Need MDS version at least 2.11.56"
19105
19106         local total=20
19107         local files_on_starting_mdt=0
19108
19109         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19110         $LFS getdirstripe $DIR/$tdir
19111         for i in $(seq $total); do
19112                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19113                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19114                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19115         done
19116
19117         echo "$files_on_starting_mdt files on MDT0"
19118
19119         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19120         $LFS getdirstripe $DIR/$tdir
19121
19122         files_on_starting_mdt=0
19123         for i in $(seq $total); do
19124                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19125                         error "file $tfile.$i mismatch after migration"
19126                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19127                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19128         done
19129
19130         echo "$files_on_starting_mdt files on MDT1 after migration"
19131         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19132
19133         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19134         $LFS getdirstripe $DIR/$tdir
19135
19136         files_on_starting_mdt=0
19137         for i in $(seq $total); do
19138                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19139                         error "file $tfile.$i mismatch after 2nd migration"
19140                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19141                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19142         done
19143
19144         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19145         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19146
19147         true
19148 }
19149 run_test 230k "file data not changed after dir migration"
19150
19151 test_230l() {
19152         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19153         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19154                 skip "Need MDS version at least 2.11.56"
19155
19156         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19157         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19158                 error "create files under remote dir failed $i"
19159         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19160 }
19161 run_test 230l "readdir between MDTs won't crash"
19162
19163 test_230m() {
19164         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19165         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19166                 skip "Need MDS version at least 2.11.56"
19167
19168         local MDTIDX=1
19169         local mig_dir=$DIR/$tdir/migrate_dir
19170         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19171         local shortstr="b"
19172         local val
19173
19174         echo "Creating files and dirs with xattrs"
19175         test_mkdir $DIR/$tdir
19176         test_mkdir -i0 -c1 $mig_dir
19177         mkdir $mig_dir/dir
19178         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19179                 error "cannot set xattr attr1 on dir"
19180         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19181                 error "cannot set xattr attr2 on dir"
19182         touch $mig_dir/dir/f0
19183         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19184                 error "cannot set xattr attr1 on file"
19185         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19186                 error "cannot set xattr attr2 on file"
19187         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19188         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19189         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19190         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19191         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19192         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19193         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19194         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19195         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19196
19197         echo "Migrating to MDT1"
19198         $LFS migrate -m $MDTIDX $mig_dir ||
19199                 error "fails on migrating dir to MDT1"
19200
19201         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19202         echo "Checking xattrs"
19203         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19204         [ "$val" = $longstr ] ||
19205                 error "expecting xattr1 $longstr on dir, found $val"
19206         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19207         [ "$val" = $shortstr ] ||
19208                 error "expecting xattr2 $shortstr on dir, found $val"
19209         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19210         [ "$val" = $longstr ] ||
19211                 error "expecting xattr1 $longstr on file, found $val"
19212         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19213         [ "$val" = $shortstr ] ||
19214                 error "expecting xattr2 $shortstr on file, found $val"
19215 }
19216 run_test 230m "xattrs not changed after dir migration"
19217
19218 test_230n() {
19219         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19220         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19221                 skip "Need MDS version at least 2.13.53"
19222
19223         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19224         cat /etc/hosts > $DIR/$tdir/$tfile
19225         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19226         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19227
19228         cmp /etc/hosts $DIR/$tdir/$tfile ||
19229                 error "File data mismatch after migration"
19230 }
19231 run_test 230n "Dir migration with mirrored file"
19232
19233 test_230o() {
19234         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19235         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19236                 skip "Need MDS version at least 2.13.52"
19237
19238         local mdts=$(comma_list $(mdts_nodes))
19239         local timeout=100
19240         local restripe_status
19241         local delta
19242         local i
19243
19244         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19245
19246         # in case "crush" hash type is not set
19247         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19248
19249         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19250                            mdt.*MDT0000.enable_dir_restripe)
19251         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19252         stack_trap "do_nodes $mdts $LCTL set_param \
19253                     mdt.*.enable_dir_restripe=$restripe_status"
19254
19255         mkdir $DIR/$tdir
19256         createmany -m $DIR/$tdir/f 100 ||
19257                 error "create files under remote dir failed $i"
19258         createmany -d $DIR/$tdir/d 100 ||
19259                 error "create dirs under remote dir failed $i"
19260
19261         for i in $(seq 2 $MDSCOUNT); do
19262                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19263                 $LFS setdirstripe -c $i $DIR/$tdir ||
19264                         error "split -c $i $tdir failed"
19265                 wait_update $HOSTNAME \
19266                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19267                         error "dir split not finished"
19268                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19269                         awk '/migrate/ {sum += $2} END { print sum }')
19270                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19271                 # delta is around total_files/stripe_count
19272                 (( $delta < 200 / (i - 1) + 4 )) ||
19273                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19274         done
19275 }
19276 run_test 230o "dir split"
19277
19278 test_230p() {
19279         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19280         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19281                 skip "Need MDS version at least 2.13.52"
19282
19283         local mdts=$(comma_list $(mdts_nodes))
19284         local timeout=100
19285         local restripe_status
19286         local delta
19287         local i
19288
19289         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19290
19291         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19292
19293         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19294                            mdt.*MDT0000.enable_dir_restripe)
19295         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19296         stack_trap "do_nodes $mdts $LCTL set_param \
19297                     mdt.*.enable_dir_restripe=$restripe_status"
19298
19299         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19300         createmany -m $DIR/$tdir/f 100 ||
19301                 error "create files under remote dir failed $i"
19302         createmany -d $DIR/$tdir/d 100 ||
19303                 error "create dirs under remote dir failed $i"
19304
19305         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19306                 local mdt_hash="crush"
19307
19308                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19309                 $LFS setdirstripe -c $i $DIR/$tdir ||
19310                         error "split -c $i $tdir failed"
19311                 [ $i -eq 1 ] && mdt_hash="none"
19312                 wait_update $HOSTNAME \
19313                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19314                         error "dir merge not finished"
19315                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19316                         awk '/migrate/ {sum += $2} END { print sum }')
19317                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19318                 # delta is around total_files/stripe_count
19319                 (( $delta < 200 / i + 4 )) ||
19320                         error "$delta files migrated >= $((200 / i + 4))"
19321         done
19322 }
19323 run_test 230p "dir merge"
19324
19325 test_230q() {
19326         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19327         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19328                 skip "Need MDS version at least 2.13.52"
19329
19330         local mdts=$(comma_list $(mdts_nodes))
19331         local saved_threshold=$(do_facet mds1 \
19332                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19333         local saved_delta=$(do_facet mds1 \
19334                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19335         local threshold=100
19336         local delta=2
19337         local total=0
19338         local stripe_count=0
19339         local stripe_index
19340         local nr_files
19341         local create
19342
19343         # test with fewer files on ZFS
19344         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19345
19346         stack_trap "do_nodes $mdts $LCTL set_param \
19347                     mdt.*.dir_split_count=$saved_threshold"
19348         stack_trap "do_nodes $mdts $LCTL set_param \
19349                     mdt.*.dir_split_delta=$saved_delta"
19350         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19351         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19352         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19353         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19354         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19355         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19356
19357         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19358         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19359
19360         create=$((threshold * 3 / 2))
19361         while [ $stripe_count -lt $MDSCOUNT ]; do
19362                 createmany -m $DIR/$tdir/f $total $create ||
19363                         error "create sub files failed"
19364                 stat $DIR/$tdir > /dev/null
19365                 total=$((total + create))
19366                 stripe_count=$((stripe_count + delta))
19367                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19368
19369                 wait_update $HOSTNAME \
19370                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19371                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19372
19373                 wait_update $HOSTNAME \
19374                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19375                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19376
19377                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19378                 echo "$nr_files/$total files on MDT$stripe_index after split"
19379                 # allow 10% margin of imbalance with crush hash
19380                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19381                         error "$nr_files files on MDT$stripe_index after split"
19382
19383                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19384                 [ $nr_files -eq $total ] ||
19385                         error "total sub files $nr_files != $total"
19386         done
19387 }
19388 run_test 230q "dir auto split"
19389
19390 test_230r() {
19391         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19392         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19393         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19394                 skip "Need MDS version at least 2.13.54"
19395
19396         # maximum amount of local locks:
19397         # parent striped dir - 2 locks
19398         # new stripe in parent to migrate to - 1 lock
19399         # source and target - 2 locks
19400         # Total 5 locks for regular file
19401         mkdir -p $DIR/$tdir
19402         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19403         touch $DIR/$tdir/dir1/eee
19404
19405         # create 4 hardlink for 4 more locks
19406         # Total: 9 locks > RS_MAX_LOCKS (8)
19407         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19408         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19409         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19410         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19411         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19412         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19413         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19414         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19415
19416         cancel_lru_locks mdc
19417
19418         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19419                 error "migrate dir fails"
19420
19421         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19422 }
19423 run_test 230r "migrate with too many local locks"
19424
19425 test_230s() {
19426         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19427                 skip "Need MDS version at least 2.13.57"
19428
19429         local mdts=$(comma_list $(mdts_nodes))
19430         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19431                                 mdt.*MDT0000.enable_dir_restripe)
19432
19433         stack_trap "do_nodes $mdts $LCTL set_param \
19434                     mdt.*.enable_dir_restripe=$restripe_status"
19435
19436         local st
19437         for st in 0 1; do
19438                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19439                 test_mkdir $DIR/$tdir
19440                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19441                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19442                 rmdir $DIR/$tdir
19443         done
19444 }
19445 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19446
19447 test_230t()
19448 {
19449         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19450         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19451                 skip "Need MDS version at least 2.14.50"
19452
19453         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19454         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19455         $LFS project -p 1 -s $DIR/$tdir ||
19456                 error "set $tdir project id failed"
19457         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19458                 error "set subdir project id failed"
19459         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19460 }
19461 run_test 230t "migrate directory with project ID set"
19462
19463 test_231a()
19464 {
19465         # For simplicity this test assumes that max_pages_per_rpc
19466         # is the same across all OSCs
19467         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19468         local bulk_size=$((max_pages * PAGE_SIZE))
19469         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19470                                        head -n 1)
19471
19472         mkdir -p $DIR/$tdir
19473         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19474                 error "failed to set stripe with -S ${brw_size}M option"
19475
19476         # clear the OSC stats
19477         $LCTL set_param osc.*.stats=0 &>/dev/null
19478         stop_writeback
19479
19480         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19481         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19482                 oflag=direct &>/dev/null || error "dd failed"
19483
19484         sync; sleep 1; sync # just to be safe
19485         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19486         if [ x$nrpcs != "x1" ]; then
19487                 $LCTL get_param osc.*.stats
19488                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19489         fi
19490
19491         start_writeback
19492         # Drop the OSC cache, otherwise we will read from it
19493         cancel_lru_locks osc
19494
19495         # clear the OSC stats
19496         $LCTL set_param osc.*.stats=0 &>/dev/null
19497
19498         # Client reads $bulk_size.
19499         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19500                 iflag=direct &>/dev/null || error "dd failed"
19501
19502         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19503         if [ x$nrpcs != "x1" ]; then
19504                 $LCTL get_param osc.*.stats
19505                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19506         fi
19507 }
19508 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19509
19510 test_231b() {
19511         mkdir -p $DIR/$tdir
19512         local i
19513         for i in {0..1023}; do
19514                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19515                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19516                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19517         done
19518         sync
19519 }
19520 run_test 231b "must not assert on fully utilized OST request buffer"
19521
19522 test_232a() {
19523         mkdir -p $DIR/$tdir
19524         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19525
19526         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19527         do_facet ost1 $LCTL set_param fail_loc=0x31c
19528
19529         # ignore dd failure
19530         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19531
19532         do_facet ost1 $LCTL set_param fail_loc=0
19533         umount_client $MOUNT || error "umount failed"
19534         mount_client $MOUNT || error "mount failed"
19535         stop ost1 || error "cannot stop ost1"
19536         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19537 }
19538 run_test 232a "failed lock should not block umount"
19539
19540 test_232b() {
19541         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19542                 skip "Need MDS version at least 2.10.58"
19543
19544         mkdir -p $DIR/$tdir
19545         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19547         sync
19548         cancel_lru_locks osc
19549
19550         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19551         do_facet ost1 $LCTL set_param fail_loc=0x31c
19552
19553         # ignore failure
19554         $LFS data_version $DIR/$tdir/$tfile || true
19555
19556         do_facet ost1 $LCTL set_param fail_loc=0
19557         umount_client $MOUNT || error "umount failed"
19558         mount_client $MOUNT || error "mount failed"
19559         stop ost1 || error "cannot stop ost1"
19560         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19561 }
19562 run_test 232b "failed data version lock should not block umount"
19563
19564 test_233a() {
19565         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19566                 skip "Need MDS version at least 2.3.64"
19567         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19568
19569         local fid=$($LFS path2fid $MOUNT)
19570
19571         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19572                 error "cannot access $MOUNT using its FID '$fid'"
19573 }
19574 run_test 233a "checking that OBF of the FS root succeeds"
19575
19576 test_233b() {
19577         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19578                 skip "Need MDS version at least 2.5.90"
19579         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19580
19581         local fid=$($LFS path2fid $MOUNT/.lustre)
19582
19583         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19584                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19585
19586         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19587         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19588                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19589 }
19590 run_test 233b "checking that OBF of the FS .lustre succeeds"
19591
19592 test_234() {
19593         local p="$TMP/sanityN-$TESTNAME.parameters"
19594         save_lustre_params client "llite.*.xattr_cache" > $p
19595         lctl set_param llite.*.xattr_cache 1 ||
19596                 skip_env "xattr cache is not supported"
19597
19598         mkdir -p $DIR/$tdir || error "mkdir failed"
19599         touch $DIR/$tdir/$tfile || error "touch failed"
19600         # OBD_FAIL_LLITE_XATTR_ENOMEM
19601         $LCTL set_param fail_loc=0x1405
19602         getfattr -n user.attr $DIR/$tdir/$tfile &&
19603                 error "getfattr should have failed with ENOMEM"
19604         $LCTL set_param fail_loc=0x0
19605         rm -rf $DIR/$tdir
19606
19607         restore_lustre_params < $p
19608         rm -f $p
19609 }
19610 run_test 234 "xattr cache should not crash on ENOMEM"
19611
19612 test_235() {
19613         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19614                 skip "Need MDS version at least 2.4.52"
19615
19616         flock_deadlock $DIR/$tfile
19617         local RC=$?
19618         case $RC in
19619                 0)
19620                 ;;
19621                 124) error "process hangs on a deadlock"
19622                 ;;
19623                 *) error "error executing flock_deadlock $DIR/$tfile"
19624                 ;;
19625         esac
19626 }
19627 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19628
19629 #LU-2935
19630 test_236() {
19631         check_swap_layouts_support
19632
19633         local ref1=/etc/passwd
19634         local ref2=/etc/group
19635         local file1=$DIR/$tdir/f1
19636         local file2=$DIR/$tdir/f2
19637
19638         test_mkdir -c1 $DIR/$tdir
19639         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19640         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19641         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19642         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19643         local fd=$(free_fd)
19644         local cmd="exec $fd<>$file2"
19645         eval $cmd
19646         rm $file2
19647         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19648                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19649         cmd="exec $fd>&-"
19650         eval $cmd
19651         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19652
19653         #cleanup
19654         rm -rf $DIR/$tdir
19655 }
19656 run_test 236 "Layout swap on open unlinked file"
19657
19658 # LU-4659 linkea consistency
19659 test_238() {
19660         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19661                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19662                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19663                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19664
19665         touch $DIR/$tfile
19666         ln $DIR/$tfile $DIR/$tfile.lnk
19667         touch $DIR/$tfile.new
19668         mv $DIR/$tfile.new $DIR/$tfile
19669         local fid1=$($LFS path2fid $DIR/$tfile)
19670         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19671         local path1=$($LFS fid2path $FSNAME "$fid1")
19672         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19673         local path2=$($LFS fid2path $FSNAME "$fid2")
19674         [ $tfile.lnk == $path2 ] ||
19675                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19676         rm -f $DIR/$tfile*
19677 }
19678 run_test 238 "Verify linkea consistency"
19679
19680 test_239A() { # was test_239
19681         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19682                 skip "Need MDS version at least 2.5.60"
19683
19684         local list=$(comma_list $(mdts_nodes))
19685
19686         mkdir -p $DIR/$tdir
19687         createmany -o $DIR/$tdir/f- 5000
19688         unlinkmany $DIR/$tdir/f- 5000
19689         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19690                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19691         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19692                         osp.*MDT*.sync_in_flight" | calc_sum)
19693         [ "$changes" -eq 0 ] || error "$changes not synced"
19694 }
19695 run_test 239A "osp_sync test"
19696
19697 test_239a() { #LU-5297
19698         remote_mds_nodsh && skip "remote MDS with nodsh"
19699
19700         touch $DIR/$tfile
19701         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19702         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19703         chgrp $RUNAS_GID $DIR/$tfile
19704         wait_delete_completed
19705 }
19706 run_test 239a "process invalid osp sync record correctly"
19707
19708 test_239b() { #LU-5297
19709         remote_mds_nodsh && skip "remote MDS with nodsh"
19710
19711         touch $DIR/$tfile1
19712         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19713         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19714         chgrp $RUNAS_GID $DIR/$tfile1
19715         wait_delete_completed
19716         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19717         touch $DIR/$tfile2
19718         chgrp $RUNAS_GID $DIR/$tfile2
19719         wait_delete_completed
19720 }
19721 run_test 239b "process osp sync record with ENOMEM error correctly"
19722
19723 test_240() {
19724         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19725         remote_mds_nodsh && skip "remote MDS with nodsh"
19726
19727         mkdir -p $DIR/$tdir
19728
19729         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19730                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19731         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19732                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19733
19734         umount_client $MOUNT || error "umount failed"
19735         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19736         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19737         mount_client $MOUNT || error "failed to mount client"
19738
19739         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19740         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19741 }
19742 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19743
19744 test_241_bio() {
19745         local count=$1
19746         local bsize=$2
19747
19748         for LOOP in $(seq $count); do
19749                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19750                 cancel_lru_locks $OSC || true
19751         done
19752 }
19753
19754 test_241_dio() {
19755         local count=$1
19756         local bsize=$2
19757
19758         for LOOP in $(seq $1); do
19759                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19760                         2>/dev/null
19761         done
19762 }
19763
19764 test_241a() { # was test_241
19765         local bsize=$PAGE_SIZE
19766
19767         (( bsize < 40960 )) && bsize=40960
19768         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19769         ls -la $DIR/$tfile
19770         cancel_lru_locks $OSC
19771         test_241_bio 1000 $bsize &
19772         PID=$!
19773         test_241_dio 1000 $bsize
19774         wait $PID
19775 }
19776 run_test 241a "bio vs dio"
19777
19778 test_241b() {
19779         local bsize=$PAGE_SIZE
19780
19781         (( bsize < 40960 )) && bsize=40960
19782         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19783         ls -la $DIR/$tfile
19784         test_241_dio 1000 $bsize &
19785         PID=$!
19786         test_241_dio 1000 $bsize
19787         wait $PID
19788 }
19789 run_test 241b "dio vs dio"
19790
19791 test_242() {
19792         remote_mds_nodsh && skip "remote MDS with nodsh"
19793
19794         mkdir -p $DIR/$tdir
19795         touch $DIR/$tdir/$tfile
19796
19797         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19798         do_facet mds1 lctl set_param fail_loc=0x105
19799         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19800
19801         do_facet mds1 lctl set_param fail_loc=0
19802         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19803 }
19804 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19805
19806 test_243()
19807 {
19808         test_mkdir $DIR/$tdir
19809         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19810 }
19811 run_test 243 "various group lock tests"
19812
19813 test_244a()
19814 {
19815         test_mkdir $DIR/$tdir
19816         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19817         sendfile_grouplock $DIR/$tdir/$tfile || \
19818                 error "sendfile+grouplock failed"
19819         rm -rf $DIR/$tdir
19820 }
19821 run_test 244a "sendfile with group lock tests"
19822
19823 test_244b()
19824 {
19825         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19826
19827         local threads=50
19828         local size=$((1024*1024))
19829
19830         test_mkdir $DIR/$tdir
19831         for i in $(seq 1 $threads); do
19832                 local file=$DIR/$tdir/file_$((i / 10))
19833                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19834                 local pids[$i]=$!
19835         done
19836         for i in $(seq 1 $threads); do
19837                 wait ${pids[$i]}
19838         done
19839 }
19840 run_test 244b "multi-threaded write with group lock"
19841
19842 test_245() {
19843         local flagname="multi_mod_rpcs"
19844         local connect_data_name="max_mod_rpcs"
19845         local out
19846
19847         # check if multiple modify RPCs flag is set
19848         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19849                 grep "connect_flags:")
19850         echo "$out"
19851
19852         echo "$out" | grep -qw $flagname
19853         if [ $? -ne 0 ]; then
19854                 echo "connect flag $flagname is not set"
19855                 return
19856         fi
19857
19858         # check if multiple modify RPCs data is set
19859         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19860         echo "$out"
19861
19862         echo "$out" | grep -qw $connect_data_name ||
19863                 error "import should have connect data $connect_data_name"
19864 }
19865 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19866
19867 cleanup_247() {
19868         local submount=$1
19869
19870         trap 0
19871         umount_client $submount
19872         rmdir $submount
19873 }
19874
19875 test_247a() {
19876         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19877                 grep -q subtree ||
19878                 skip_env "Fileset feature is not supported"
19879
19880         local submount=${MOUNT}_$tdir
19881
19882         mkdir $MOUNT/$tdir
19883         mkdir -p $submount || error "mkdir $submount failed"
19884         FILESET="$FILESET/$tdir" mount_client $submount ||
19885                 error "mount $submount failed"
19886         trap "cleanup_247 $submount" EXIT
19887         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19888         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19889                 error "read $MOUNT/$tdir/$tfile failed"
19890         cleanup_247 $submount
19891 }
19892 run_test 247a "mount subdir as fileset"
19893
19894 test_247b() {
19895         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19896                 skip_env "Fileset feature is not supported"
19897
19898         local submount=${MOUNT}_$tdir
19899
19900         rm -rf $MOUNT/$tdir
19901         mkdir -p $submount || error "mkdir $submount failed"
19902         SKIP_FILESET=1
19903         FILESET="$FILESET/$tdir" mount_client $submount &&
19904                 error "mount $submount should fail"
19905         rmdir $submount
19906 }
19907 run_test 247b "mount subdir that dose not exist"
19908
19909 test_247c() {
19910         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19911                 skip_env "Fileset feature is not supported"
19912
19913         local submount=${MOUNT}_$tdir
19914
19915         mkdir -p $MOUNT/$tdir/dir1
19916         mkdir -p $submount || error "mkdir $submount failed"
19917         trap "cleanup_247 $submount" EXIT
19918         FILESET="$FILESET/$tdir" mount_client $submount ||
19919                 error "mount $submount failed"
19920         local fid=$($LFS path2fid $MOUNT/)
19921         $LFS fid2path $submount $fid && error "fid2path should fail"
19922         cleanup_247 $submount
19923 }
19924 run_test 247c "running fid2path outside subdirectory root"
19925
19926 test_247d() {
19927         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19928                 skip "Fileset feature is not supported"
19929
19930         local submount=${MOUNT}_$tdir
19931
19932         mkdir -p $MOUNT/$tdir/dir1
19933         mkdir -p $submount || error "mkdir $submount failed"
19934         FILESET="$FILESET/$tdir" mount_client $submount ||
19935                 error "mount $submount failed"
19936         trap "cleanup_247 $submount" EXIT
19937
19938         local td=$submount/dir1
19939         local fid=$($LFS path2fid $td)
19940         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19941
19942         # check that we get the same pathname back
19943         local rootpath
19944         local found
19945         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19946                 echo "$rootpath $fid"
19947                 found=$($LFS fid2path $rootpath "$fid")
19948                 [ -n "found" ] || error "fid2path should succeed"
19949                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19950         done
19951         # check wrong root path format
19952         rootpath=$submount"_wrong"
19953         found=$($LFS fid2path $rootpath "$fid")
19954         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19955
19956         cleanup_247 $submount
19957 }
19958 run_test 247d "running fid2path inside subdirectory root"
19959
19960 # LU-8037
19961 test_247e() {
19962         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19963                 grep -q subtree ||
19964                 skip "Fileset feature is not supported"
19965
19966         local submount=${MOUNT}_$tdir
19967
19968         mkdir $MOUNT/$tdir
19969         mkdir -p $submount || error "mkdir $submount failed"
19970         FILESET="$FILESET/.." mount_client $submount &&
19971                 error "mount $submount should fail"
19972         rmdir $submount
19973 }
19974 run_test 247e "mount .. as fileset"
19975
19976 test_247f() {
19977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19978         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19979                 skip "Need at least version 2.13.52"
19980         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19981                 skip "Need at least version 2.14.50"
19982         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19983                 grep -q subtree ||
19984                 skip "Fileset feature is not supported"
19985
19986         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19987         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19988                 error "mkdir remote failed"
19989         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19990         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19991                 error "mkdir striped failed"
19992         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19993
19994         local submount=${MOUNT}_$tdir
19995
19996         mkdir -p $submount || error "mkdir $submount failed"
19997         stack_trap "rmdir $submount"
19998
19999         local dir
20000         local stat
20001         local fileset=$FILESET
20002         local mdts=$(comma_list $(mdts_nodes))
20003
20004         stat=$(do_facet mds1 $LCTL get_param -n \
20005                 mdt.*MDT0000.enable_remote_subdir_mount)
20006         stack_trap "do_nodes $mdts $LCTL set_param \
20007                 mdt.*.enable_remote_subdir_mount=$stat"
20008
20009         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20010         stack_trap "umount_client $submount"
20011         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20012                 error "mount remote dir $dir should fail"
20013
20014         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20015                 $tdir/striped/. ; do
20016                 FILESET="$fileset/$dir" mount_client $submount ||
20017                         error "mount $dir failed"
20018                 umount_client $submount
20019         done
20020
20021         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20022         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20023                 error "mount $tdir/remote failed"
20024 }
20025 run_test 247f "mount striped or remote directory as fileset"
20026
20027 test_247g() {
20028         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20029         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20030                 skip "Need at least version 2.14.50"
20031
20032         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20033                 error "mkdir $tdir failed"
20034         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20035
20036         local submount=${MOUNT}_$tdir
20037
20038         mkdir -p $submount || error "mkdir $submount failed"
20039         stack_trap "rmdir $submount"
20040
20041         FILESET="$fileset/$tdir" mount_client $submount ||
20042                 error "mount $dir failed"
20043         stack_trap "umount $submount"
20044
20045         local mdts=$(comma_list $(mdts_nodes))
20046
20047         local nrpcs
20048
20049         stat $submount > /dev/null
20050         cancel_lru_locks $MDC
20051         stat $submount > /dev/null
20052         stat $submount/$tfile > /dev/null
20053         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20054         stat $submount/$tfile > /dev/null
20055         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20056                 awk '/getattr/ {sum += $2} END {print sum}')
20057
20058         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20059 }
20060 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20061
20062 test_248a() {
20063         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20064         [ -z "$fast_read_sav" ] && skip "no fast read support"
20065
20066         # create a large file for fast read verification
20067         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20068
20069         # make sure the file is created correctly
20070         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20071                 { rm -f $DIR/$tfile; skip "file creation error"; }
20072
20073         echo "Test 1: verify that fast read is 4 times faster on cache read"
20074
20075         # small read with fast read enabled
20076         $LCTL set_param -n llite.*.fast_read=1
20077         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20078                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20079                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20080         # small read with fast read disabled
20081         $LCTL set_param -n llite.*.fast_read=0
20082         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20083                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20084                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20085
20086         # verify that fast read is 4 times faster for cache read
20087         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20088                 error_not_in_vm "fast read was not 4 times faster: " \
20089                            "$t_fast vs $t_slow"
20090
20091         echo "Test 2: verify the performance between big and small read"
20092         $LCTL set_param -n llite.*.fast_read=1
20093
20094         # 1k non-cache read
20095         cancel_lru_locks osc
20096         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20097                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20098                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20099
20100         # 1M non-cache read
20101         cancel_lru_locks osc
20102         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20103                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20104                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20105
20106         # verify that big IO is not 4 times faster than small IO
20107         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20108                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20109
20110         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20111         rm -f $DIR/$tfile
20112 }
20113 run_test 248a "fast read verification"
20114
20115 test_248b() {
20116         # Default short_io_bytes=16384, try both smaller and larger sizes.
20117         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20118         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20119         echo "bs=53248 count=113 normal buffered write"
20120         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20121                 error "dd of initial data file failed"
20122         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20123
20124         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20125         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20126                 error "dd with sync normal writes failed"
20127         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20128
20129         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20130         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20131                 error "dd with sync small writes failed"
20132         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20133
20134         cancel_lru_locks osc
20135
20136         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20137         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20138         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20139         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20140                 iflag=direct || error "dd with O_DIRECT small read failed"
20141         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20142         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20143                 error "compare $TMP/$tfile.1 failed"
20144
20145         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20146         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20147
20148         # just to see what the maximum tunable value is, and test parsing
20149         echo "test invalid parameter 2MB"
20150         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20151                 error "too-large short_io_bytes allowed"
20152         echo "test maximum parameter 512KB"
20153         # if we can set a larger short_io_bytes, run test regardless of version
20154         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20155                 # older clients may not allow setting it this large, that's OK
20156                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20157                         skip "Need at least client version 2.13.50"
20158                 error "medium short_io_bytes failed"
20159         fi
20160         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20161         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20162
20163         echo "test large parameter 64KB"
20164         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20165         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20166
20167         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20168         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20169                 error "dd with sync large writes failed"
20170         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20171
20172         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20173         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20174         num=$((113 * 4096 / PAGE_SIZE))
20175         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20176         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20177                 error "dd with O_DIRECT large writes failed"
20178         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20179                 error "compare $DIR/$tfile.3 failed"
20180
20181         cancel_lru_locks osc
20182
20183         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20184         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20185                 error "dd with O_DIRECT large read failed"
20186         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20187                 error "compare $TMP/$tfile.2 failed"
20188
20189         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20190         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20191                 error "dd with O_DIRECT large read failed"
20192         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20193                 error "compare $TMP/$tfile.3 failed"
20194 }
20195 run_test 248b "test short_io read and write for both small and large sizes"
20196
20197 test_249() { # LU-7890
20198         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20199                 skip "Need at least version 2.8.54"
20200
20201         rm -f $DIR/$tfile
20202         $LFS setstripe -c 1 $DIR/$tfile
20203         # Offset 2T == 4k * 512M
20204         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20205                 error "dd to 2T offset failed"
20206 }
20207 run_test 249 "Write above 2T file size"
20208
20209 test_250() {
20210         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20211          && skip "no 16TB file size limit on ZFS"
20212
20213         $LFS setstripe -c 1 $DIR/$tfile
20214         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20215         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20216         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20217         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20218                 conv=notrunc,fsync && error "append succeeded"
20219         return 0
20220 }
20221 run_test 250 "Write above 16T limit"
20222
20223 test_251() {
20224         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20225
20226         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20227         #Skip once - writing the first stripe will succeed
20228         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20229         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20230                 error "short write happened"
20231
20232         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20233         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20234                 error "short read happened"
20235
20236         rm -f $DIR/$tfile
20237 }
20238 run_test 251 "Handling short read and write correctly"
20239
20240 test_252() {
20241         remote_mds_nodsh && skip "remote MDS with nodsh"
20242         remote_ost_nodsh && skip "remote OST with nodsh"
20243         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20244                 skip_env "ldiskfs only test"
20245         fi
20246
20247         local tgt
20248         local dev
20249         local out
20250         local uuid
20251         local num
20252         local gen
20253
20254         # check lr_reader on OST0000
20255         tgt=ost1
20256         dev=$(facet_device $tgt)
20257         out=$(do_facet $tgt $LR_READER $dev)
20258         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20259         echo "$out"
20260         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20261         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20262                 error "Invalid uuid returned by $LR_READER on target $tgt"
20263         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20264
20265         # check lr_reader -c on MDT0000
20266         tgt=mds1
20267         dev=$(facet_device $tgt)
20268         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20269                 skip "$LR_READER does not support additional options"
20270         fi
20271         out=$(do_facet $tgt $LR_READER -c $dev)
20272         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20273         echo "$out"
20274         num=$(echo "$out" | grep -c "mdtlov")
20275         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20276                 error "Invalid number of mdtlov clients returned by $LR_READER"
20277         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20278
20279         # check lr_reader -cr on MDT0000
20280         out=$(do_facet $tgt $LR_READER -cr $dev)
20281         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20282         echo "$out"
20283         echo "$out" | grep -q "^reply_data:$" ||
20284                 error "$LR_READER should have returned 'reply_data' section"
20285         num=$(echo "$out" | grep -c "client_generation")
20286         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20287 }
20288 run_test 252 "check lr_reader tool"
20289
20290 test_253() {
20291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20292         remote_mds_nodsh && skip "remote MDS with nodsh"
20293         remote_mgs_nodsh && skip "remote MGS with nodsh"
20294
20295         local ostidx=0
20296         local rc=0
20297         local ost_name=$(ostname_from_index $ostidx)
20298
20299         # on the mdt's osc
20300         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20301         do_facet $SINGLEMDS $LCTL get_param -n \
20302                 osp.$mdtosc_proc1.reserved_mb_high ||
20303                 skip  "remote MDS does not support reserved_mb_high"
20304
20305         rm -rf $DIR/$tdir
20306         wait_mds_ost_sync
20307         wait_delete_completed
20308         mkdir $DIR/$tdir
20309
20310         pool_add $TESTNAME || error "Pool creation failed"
20311         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20312
20313         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20314                 error "Setstripe failed"
20315
20316         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20317
20318         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20319                     grep "watermarks")
20320         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20321
20322         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20323                         osp.$mdtosc_proc1.prealloc_status)
20324         echo "prealloc_status $oa_status"
20325
20326         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20327                 error "File creation should fail"
20328
20329         #object allocation was stopped, but we still able to append files
20330         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20331                 oflag=append || error "Append failed"
20332
20333         rm -f $DIR/$tdir/$tfile.0
20334
20335         # For this test, we want to delete the files we created to go out of
20336         # space but leave the watermark, so we remain nearly out of space
20337         ost_watermarks_enospc_delete_files $tfile $ostidx
20338
20339         wait_delete_completed
20340
20341         sleep_maxage
20342
20343         for i in $(seq 10 12); do
20344                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20345                         2>/dev/null || error "File creation failed after rm"
20346         done
20347
20348         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20349                         osp.$mdtosc_proc1.prealloc_status)
20350         echo "prealloc_status $oa_status"
20351
20352         if (( oa_status != 0 )); then
20353                 error "Object allocation still disable after rm"
20354         fi
20355 }
20356 run_test 253 "Check object allocation limit"
20357
20358 test_254() {
20359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20360         remote_mds_nodsh && skip "remote MDS with nodsh"
20361         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20362                 skip "MDS does not support changelog_size"
20363
20364         local cl_user
20365         local MDT0=$(facet_svc $SINGLEMDS)
20366
20367         changelog_register || error "changelog_register failed"
20368
20369         changelog_clear 0 || error "changelog_clear failed"
20370
20371         local size1=$(do_facet $SINGLEMDS \
20372                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20373         echo "Changelog size $size1"
20374
20375         rm -rf $DIR/$tdir
20376         $LFS mkdir -i 0 $DIR/$tdir
20377         # change something
20378         mkdir -p $DIR/$tdir/pics/2008/zachy
20379         touch $DIR/$tdir/pics/2008/zachy/timestamp
20380         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20381         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20382         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20383         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20384         rm $DIR/$tdir/pics/desktop.jpg
20385
20386         local size2=$(do_facet $SINGLEMDS \
20387                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20388         echo "Changelog size after work $size2"
20389
20390         (( $size2 > $size1 )) ||
20391                 error "new Changelog size=$size2 less than old size=$size1"
20392 }
20393 run_test 254 "Check changelog size"
20394
20395 ladvise_no_type()
20396 {
20397         local type=$1
20398         local file=$2
20399
20400         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20401                 awk -F: '{print $2}' | grep $type > /dev/null
20402         if [ $? -ne 0 ]; then
20403                 return 0
20404         fi
20405         return 1
20406 }
20407
20408 ladvise_no_ioctl()
20409 {
20410         local file=$1
20411
20412         lfs ladvise -a willread $file > /dev/null 2>&1
20413         if [ $? -eq 0 ]; then
20414                 return 1
20415         fi
20416
20417         lfs ladvise -a willread $file 2>&1 |
20418                 grep "Inappropriate ioctl for device" > /dev/null
20419         if [ $? -eq 0 ]; then
20420                 return 0
20421         fi
20422         return 1
20423 }
20424
20425 percent() {
20426         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20427 }
20428
20429 # run a random read IO workload
20430 # usage: random_read_iops <filename> <filesize> <iosize>
20431 random_read_iops() {
20432         local file=$1
20433         local fsize=$2
20434         local iosize=${3:-4096}
20435
20436         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20437                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20438 }
20439
20440 drop_file_oss_cache() {
20441         local file="$1"
20442         local nodes="$2"
20443
20444         $LFS ladvise -a dontneed $file 2>/dev/null ||
20445                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20446 }
20447
20448 ladvise_willread_performance()
20449 {
20450         local repeat=10
20451         local average_origin=0
20452         local average_cache=0
20453         local average_ladvise=0
20454
20455         for ((i = 1; i <= $repeat; i++)); do
20456                 echo "Iter $i/$repeat: reading without willread hint"
20457                 cancel_lru_locks osc
20458                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20459                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20460                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20461                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20462
20463                 cancel_lru_locks osc
20464                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20465                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20466                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20467
20468                 cancel_lru_locks osc
20469                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20470                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20471                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20472                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20473                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20474         done
20475         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20476         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20477         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20478
20479         speedup_cache=$(percent $average_cache $average_origin)
20480         speedup_ladvise=$(percent $average_ladvise $average_origin)
20481
20482         echo "Average uncached read: $average_origin"
20483         echo "Average speedup with OSS cached read: " \
20484                 "$average_cache = +$speedup_cache%"
20485         echo "Average speedup with ladvise willread: " \
20486                 "$average_ladvise = +$speedup_ladvise%"
20487
20488         local lowest_speedup=20
20489         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20490                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20491                         "got $average_cache%. Skipping ladvise willread check."
20492                 return 0
20493         fi
20494
20495         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20496         # it is still good to run until then to exercise 'ladvise willread'
20497         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20498                 [ "$ost1_FSTYPE" = "zfs" ] &&
20499                 echo "osd-zfs does not support dontneed or drop_caches" &&
20500                 return 0
20501
20502         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20503         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20504                 error_not_in_vm "Speedup with willread is less than " \
20505                         "$lowest_speedup%, got $average_ladvise%"
20506 }
20507
20508 test_255a() {
20509         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20510                 skip "lustre < 2.8.54 does not support ladvise "
20511         remote_ost_nodsh && skip "remote OST with nodsh"
20512
20513         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20514
20515         ladvise_no_type willread $DIR/$tfile &&
20516                 skip "willread ladvise is not supported"
20517
20518         ladvise_no_ioctl $DIR/$tfile &&
20519                 skip "ladvise ioctl is not supported"
20520
20521         local size_mb=100
20522         local size=$((size_mb * 1048576))
20523         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20524                 error "dd to $DIR/$tfile failed"
20525
20526         lfs ladvise -a willread $DIR/$tfile ||
20527                 error "Ladvise failed with no range argument"
20528
20529         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20530                 error "Ladvise failed with no -l or -e argument"
20531
20532         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20533                 error "Ladvise failed with only -e argument"
20534
20535         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20536                 error "Ladvise failed with only -l argument"
20537
20538         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20539                 error "End offset should not be smaller than start offset"
20540
20541         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20542                 error "End offset should not be equal to start offset"
20543
20544         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20545                 error "Ladvise failed with overflowing -s argument"
20546
20547         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20548                 error "Ladvise failed with overflowing -e argument"
20549
20550         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20551                 error "Ladvise failed with overflowing -l argument"
20552
20553         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20554                 error "Ladvise succeeded with conflicting -l and -e arguments"
20555
20556         echo "Synchronous ladvise should wait"
20557         local delay=4
20558 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20559         do_nodes $(comma_list $(osts_nodes)) \
20560                 $LCTL set_param fail_val=$delay fail_loc=0x237
20561
20562         local start_ts=$SECONDS
20563         lfs ladvise -a willread $DIR/$tfile ||
20564                 error "Ladvise failed with no range argument"
20565         local end_ts=$SECONDS
20566         local inteval_ts=$((end_ts - start_ts))
20567
20568         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20569                 error "Synchronous advice didn't wait reply"
20570         fi
20571
20572         echo "Asynchronous ladvise shouldn't wait"
20573         local start_ts=$SECONDS
20574         lfs ladvise -a willread -b $DIR/$tfile ||
20575                 error "Ladvise failed with no range argument"
20576         local end_ts=$SECONDS
20577         local inteval_ts=$((end_ts - start_ts))
20578
20579         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20580                 error "Asynchronous advice blocked"
20581         fi
20582
20583         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20584         ladvise_willread_performance
20585 }
20586 run_test 255a "check 'lfs ladvise -a willread'"
20587
20588 facet_meminfo() {
20589         local facet=$1
20590         local info=$2
20591
20592         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20593 }
20594
20595 test_255b() {
20596         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20597                 skip "lustre < 2.8.54 does not support ladvise "
20598         remote_ost_nodsh && skip "remote OST with nodsh"
20599
20600         lfs setstripe -c 1 -i 0 $DIR/$tfile
20601
20602         ladvise_no_type dontneed $DIR/$tfile &&
20603                 skip "dontneed ladvise is not supported"
20604
20605         ladvise_no_ioctl $DIR/$tfile &&
20606                 skip "ladvise ioctl is not supported"
20607
20608         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20609                 [ "$ost1_FSTYPE" = "zfs" ] &&
20610                 skip "zfs-osd does not support 'ladvise dontneed'"
20611
20612         local size_mb=100
20613         local size=$((size_mb * 1048576))
20614         # In order to prevent disturbance of other processes, only check 3/4
20615         # of the memory usage
20616         local kibibytes=$((size_mb * 1024 * 3 / 4))
20617
20618         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20619                 error "dd to $DIR/$tfile failed"
20620
20621         #force write to complete before dropping OST cache & checking memory
20622         sync
20623
20624         local total=$(facet_meminfo ost1 MemTotal)
20625         echo "Total memory: $total KiB"
20626
20627         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20628         local before_read=$(facet_meminfo ost1 Cached)
20629         echo "Cache used before read: $before_read KiB"
20630
20631         lfs ladvise -a willread $DIR/$tfile ||
20632                 error "Ladvise willread failed"
20633         local after_read=$(facet_meminfo ost1 Cached)
20634         echo "Cache used after read: $after_read KiB"
20635
20636         lfs ladvise -a dontneed $DIR/$tfile ||
20637                 error "Ladvise dontneed again failed"
20638         local no_read=$(facet_meminfo ost1 Cached)
20639         echo "Cache used after dontneed ladvise: $no_read KiB"
20640
20641         if [ $total -lt $((before_read + kibibytes)) ]; then
20642                 echo "Memory is too small, abort checking"
20643                 return 0
20644         fi
20645
20646         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20647                 error "Ladvise willread should use more memory" \
20648                         "than $kibibytes KiB"
20649         fi
20650
20651         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20652                 error "Ladvise dontneed should release more memory" \
20653                         "than $kibibytes KiB"
20654         fi
20655 }
20656 run_test 255b "check 'lfs ladvise -a dontneed'"
20657
20658 test_255c() {
20659         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20660                 skip "lustre < 2.10.50 does not support lockahead"
20661
20662         local ost1_imp=$(get_osc_import_name client ost1)
20663         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20664                          cut -d'.' -f2)
20665         local count
20666         local new_count
20667         local difference
20668         local i
20669         local rc
20670
20671         test_mkdir -p $DIR/$tdir
20672         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20673
20674         #test 10 returns only success/failure
20675         i=10
20676         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20677         rc=$?
20678         if [ $rc -eq 255 ]; then
20679                 error "Ladvise test${i} failed, ${rc}"
20680         fi
20681
20682         #test 11 counts lock enqueue requests, all others count new locks
20683         i=11
20684         count=$(do_facet ost1 \
20685                 $LCTL get_param -n ost.OSS.ost.stats)
20686         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20687
20688         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20689         rc=$?
20690         if [ $rc -eq 255 ]; then
20691                 error "Ladvise test${i} failed, ${rc}"
20692         fi
20693
20694         new_count=$(do_facet ost1 \
20695                 $LCTL get_param -n ost.OSS.ost.stats)
20696         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20697                    awk '{ print $2 }')
20698
20699         difference="$((new_count - count))"
20700         if [ $difference -ne $rc ]; then
20701                 error "Ladvise test${i}, bad enqueue count, returned " \
20702                       "${rc}, actual ${difference}"
20703         fi
20704
20705         for i in $(seq 12 21); do
20706                 # If we do not do this, we run the risk of having too many
20707                 # locks and starting lock cancellation while we are checking
20708                 # lock counts.
20709                 cancel_lru_locks osc
20710
20711                 count=$($LCTL get_param -n \
20712                        ldlm.namespaces.$imp_name.lock_unused_count)
20713
20714                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20715                 rc=$?
20716                 if [ $rc -eq 255 ]; then
20717                         error "Ladvise test ${i} failed, ${rc}"
20718                 fi
20719
20720                 new_count=$($LCTL get_param -n \
20721                        ldlm.namespaces.$imp_name.lock_unused_count)
20722                 difference="$((new_count - count))"
20723
20724                 # Test 15 output is divided by 100 to map down to valid return
20725                 if [ $i -eq 15 ]; then
20726                         rc="$((rc * 100))"
20727                 fi
20728
20729                 if [ $difference -ne $rc ]; then
20730                         error "Ladvise test ${i}, bad lock count, returned " \
20731                               "${rc}, actual ${difference}"
20732                 fi
20733         done
20734
20735         #test 22 returns only success/failure
20736         i=22
20737         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20738         rc=$?
20739         if [ $rc -eq 255 ]; then
20740                 error "Ladvise test${i} failed, ${rc}"
20741         fi
20742 }
20743 run_test 255c "suite of ladvise lockahead tests"
20744
20745 test_256() {
20746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20747         remote_mds_nodsh && skip "remote MDS with nodsh"
20748         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20749         changelog_users $SINGLEMDS | grep "^cl" &&
20750                 skip "active changelog user"
20751
20752         local cl_user
20753         local cat_sl
20754         local mdt_dev
20755
20756         mdt_dev=$(mdsdevname 1)
20757         echo $mdt_dev
20758
20759         changelog_register || error "changelog_register failed"
20760
20761         rm -rf $DIR/$tdir
20762         mkdir -p $DIR/$tdir
20763
20764         changelog_clear 0 || error "changelog_clear failed"
20765
20766         # change something
20767         touch $DIR/$tdir/{1..10}
20768
20769         # stop the MDT
20770         stop $SINGLEMDS || error "Fail to stop MDT"
20771
20772         # remount the MDT
20773
20774         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20775
20776         #after mount new plainllog is used
20777         touch $DIR/$tdir/{11..19}
20778         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20779         stack_trap "rm -f $tmpfile"
20780         cat_sl=$(do_facet $SINGLEMDS "sync; \
20781                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20782                  llog_reader $tmpfile | grep -c type=1064553b")
20783         do_facet $SINGLEMDS llog_reader $tmpfile
20784
20785         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20786
20787         changelog_clear 0 || error "changelog_clear failed"
20788
20789         cat_sl=$(do_facet $SINGLEMDS "sync; \
20790                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20791                  llog_reader $tmpfile | grep -c type=1064553b")
20792
20793         if (( cat_sl == 2 )); then
20794                 error "Empty plain llog was not deleted from changelog catalog"
20795         elif (( cat_sl != 1 )); then
20796                 error "Active plain llog shouldn't be deleted from catalog"
20797         fi
20798 }
20799 run_test 256 "Check llog delete for empty and not full state"
20800
20801 test_257() {
20802         remote_mds_nodsh && skip "remote MDS with nodsh"
20803         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20804                 skip "Need MDS version at least 2.8.55"
20805
20806         test_mkdir $DIR/$tdir
20807
20808         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20809                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20810         stat $DIR/$tdir
20811
20812 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20813         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20814         local facet=mds$((mdtidx + 1))
20815         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20816         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20817
20818         stop $facet || error "stop MDS failed"
20819         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20820                 error "start MDS fail"
20821         wait_recovery_complete $facet
20822 }
20823 run_test 257 "xattr locks are not lost"
20824
20825 # Verify we take the i_mutex when security requires it
20826 test_258a() {
20827 #define OBD_FAIL_IMUTEX_SEC 0x141c
20828         $LCTL set_param fail_loc=0x141c
20829         touch $DIR/$tfile
20830         chmod u+s $DIR/$tfile
20831         chmod a+rwx $DIR/$tfile
20832         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20833         RC=$?
20834         if [ $RC -ne 0 ]; then
20835                 error "error, failed to take i_mutex, rc=$?"
20836         fi
20837         rm -f $DIR/$tfile
20838 }
20839 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20840
20841 # Verify we do NOT take the i_mutex in the normal case
20842 test_258b() {
20843 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20844         $LCTL set_param fail_loc=0x141d
20845         touch $DIR/$tfile
20846         chmod a+rwx $DIR
20847         chmod a+rw $DIR/$tfile
20848         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20849         RC=$?
20850         if [ $RC -ne 0 ]; then
20851                 error "error, took i_mutex unnecessarily, rc=$?"
20852         fi
20853         rm -f $DIR/$tfile
20854
20855 }
20856 run_test 258b "verify i_mutex security behavior"
20857
20858 test_259() {
20859         local file=$DIR/$tfile
20860         local before
20861         local after
20862
20863         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20864
20865         stack_trap "rm -f $file" EXIT
20866
20867         wait_delete_completed
20868         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20869         echo "before: $before"
20870
20871         $LFS setstripe -i 0 -c 1 $file
20872         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20873         sync_all_data
20874         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20875         echo "after write: $after"
20876
20877 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20878         do_facet ost1 $LCTL set_param fail_loc=0x2301
20879         $TRUNCATE $file 0
20880         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20881         echo "after truncate: $after"
20882
20883         stop ost1
20884         do_facet ost1 $LCTL set_param fail_loc=0
20885         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20886         sleep 2
20887         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20888         echo "after restart: $after"
20889         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20890                 error "missing truncate?"
20891
20892         return 0
20893 }
20894 run_test 259 "crash at delayed truncate"
20895
20896 test_260() {
20897 #define OBD_FAIL_MDC_CLOSE               0x806
20898         $LCTL set_param fail_loc=0x80000806
20899         touch $DIR/$tfile
20900
20901 }
20902 run_test 260 "Check mdc_close fail"
20903
20904 ### Data-on-MDT sanity tests ###
20905 test_270a() {
20906         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20907                 skip "Need MDS version at least 2.10.55 for DoM"
20908
20909         # create DoM file
20910         local dom=$DIR/$tdir/dom_file
20911         local tmp=$DIR/$tdir/tmp_file
20912
20913         mkdir -p $DIR/$tdir
20914
20915         # basic checks for DoM component creation
20916         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20917                 error "Can set MDT layout to non-first entry"
20918
20919         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20920                 error "Can define multiple entries as MDT layout"
20921
20922         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20923
20924         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20925         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20926         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20927
20928         local mdtidx=$($LFS getstripe -m $dom)
20929         local mdtname=MDT$(printf %04x $mdtidx)
20930         local facet=mds$((mdtidx + 1))
20931         local space_check=1
20932
20933         # Skip free space checks with ZFS
20934         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20935
20936         # write
20937         sync
20938         local size_tmp=$((65536 * 3))
20939         local mdtfree1=$(do_facet $facet \
20940                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20941
20942         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20943         # check also direct IO along write
20944         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20945         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20946         sync
20947         cmp $tmp $dom || error "file data is different"
20948         [ $(stat -c%s $dom) == $size_tmp ] ||
20949                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20950         if [ $space_check == 1 ]; then
20951                 local mdtfree2=$(do_facet $facet \
20952                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20953
20954                 # increase in usage from by $size_tmp
20955                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20956                         error "MDT free space wrong after write: " \
20957                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20958         fi
20959
20960         # truncate
20961         local size_dom=10000
20962
20963         $TRUNCATE $dom $size_dom
20964         [ $(stat -c%s $dom) == $size_dom ] ||
20965                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20966         if [ $space_check == 1 ]; then
20967                 mdtfree1=$(do_facet $facet \
20968                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20969                 # decrease in usage from $size_tmp to new $size_dom
20970                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20971                   $(((size_tmp - size_dom) / 1024)) ] ||
20972                         error "MDT free space is wrong after truncate: " \
20973                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20974         fi
20975
20976         # append
20977         cat $tmp >> $dom
20978         sync
20979         size_dom=$((size_dom + size_tmp))
20980         [ $(stat -c%s $dom) == $size_dom ] ||
20981                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20982         if [ $space_check == 1 ]; then
20983                 mdtfree2=$(do_facet $facet \
20984                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20985                 # increase in usage by $size_tmp from previous
20986                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20987                         error "MDT free space is wrong after append: " \
20988                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20989         fi
20990
20991         # delete
20992         rm $dom
20993         if [ $space_check == 1 ]; then
20994                 mdtfree1=$(do_facet $facet \
20995                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20996                 # decrease in usage by $size_dom from previous
20997                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20998                         error "MDT free space is wrong after removal: " \
20999                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21000         fi
21001
21002         # combined striping
21003         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21004                 error "Can't create DoM + OST striping"
21005
21006         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21007         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21008         # check also direct IO along write
21009         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21010         sync
21011         cmp $tmp $dom || error "file data is different"
21012         [ $(stat -c%s $dom) == $size_tmp ] ||
21013                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21014         rm $dom $tmp
21015
21016         return 0
21017 }
21018 run_test 270a "DoM: basic functionality tests"
21019
21020 test_270b() {
21021         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21022                 skip "Need MDS version at least 2.10.55"
21023
21024         local dom=$DIR/$tdir/dom_file
21025         local max_size=1048576
21026
21027         mkdir -p $DIR/$tdir
21028         $LFS setstripe -E $max_size -L mdt $dom
21029
21030         # truncate over the limit
21031         $TRUNCATE $dom $(($max_size + 1)) &&
21032                 error "successful truncate over the maximum size"
21033         # write over the limit
21034         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21035                 error "successful write over the maximum size"
21036         # append over the limit
21037         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21038         echo "12345" >> $dom && error "successful append over the maximum size"
21039         rm $dom
21040
21041         return 0
21042 }
21043 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21044
21045 test_270c() {
21046         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21047                 skip "Need MDS version at least 2.10.55"
21048
21049         mkdir -p $DIR/$tdir
21050         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21051
21052         # check files inherit DoM EA
21053         touch $DIR/$tdir/first
21054         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21055                 error "bad pattern"
21056         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21057                 error "bad stripe count"
21058         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21059                 error "bad stripe size"
21060
21061         # check directory inherits DoM EA and uses it as default
21062         mkdir $DIR/$tdir/subdir
21063         touch $DIR/$tdir/subdir/second
21064         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21065                 error "bad pattern in sub-directory"
21066         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21067                 error "bad stripe count in sub-directory"
21068         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21069                 error "bad stripe size in sub-directory"
21070         return 0
21071 }
21072 run_test 270c "DoM: DoM EA inheritance tests"
21073
21074 test_270d() {
21075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21076                 skip "Need MDS version at least 2.10.55"
21077
21078         mkdir -p $DIR/$tdir
21079         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21080
21081         # inherit default DoM striping
21082         mkdir $DIR/$tdir/subdir
21083         touch $DIR/$tdir/subdir/f1
21084
21085         # change default directory striping
21086         $LFS setstripe -c 1 $DIR/$tdir/subdir
21087         touch $DIR/$tdir/subdir/f2
21088         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21089                 error "wrong default striping in file 2"
21090         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21091                 error "bad pattern in file 2"
21092         return 0
21093 }
21094 run_test 270d "DoM: change striping from DoM to RAID0"
21095
21096 test_270e() {
21097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21098                 skip "Need MDS version at least 2.10.55"
21099
21100         mkdir -p $DIR/$tdir/dom
21101         mkdir -p $DIR/$tdir/norm
21102         DOMFILES=20
21103         NORMFILES=10
21104         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21105         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21106
21107         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21108         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21109
21110         # find DoM files by layout
21111         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21112         [ $NUM -eq  $DOMFILES ] ||
21113                 error "lfs find -L: found $NUM, expected $DOMFILES"
21114         echo "Test 1: lfs find 20 DOM files by layout: OK"
21115
21116         # there should be 1 dir with default DOM striping
21117         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21118         [ $NUM -eq  1 ] ||
21119                 error "lfs find -L: found $NUM, expected 1 dir"
21120         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21121
21122         # find DoM files by stripe size
21123         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21124         [ $NUM -eq  $DOMFILES ] ||
21125                 error "lfs find -S: found $NUM, expected $DOMFILES"
21126         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21127
21128         # find files by stripe offset except DoM files
21129         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21130         [ $NUM -eq  $NORMFILES ] ||
21131                 error "lfs find -i: found $NUM, expected $NORMFILES"
21132         echo "Test 5: lfs find no DOM files by stripe index: OK"
21133         return 0
21134 }
21135 run_test 270e "DoM: lfs find with DoM files test"
21136
21137 test_270f() {
21138         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21139                 skip "Need MDS version at least 2.10.55"
21140
21141         local mdtname=${FSNAME}-MDT0000-mdtlov
21142         local dom=$DIR/$tdir/dom_file
21143         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21144                                                 lod.$mdtname.dom_stripesize)
21145         local dom_limit=131072
21146
21147         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21148         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21149                                                 lod.$mdtname.dom_stripesize)
21150         [ ${dom_limit} -eq ${dom_current} ] ||
21151                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21152
21153         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21154         $LFS setstripe -d $DIR/$tdir
21155         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21156                 error "Can't set directory default striping"
21157
21158         # exceed maximum stripe size
21159         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21160                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21161         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21162                 error "Able to create DoM component size more than LOD limit"
21163
21164         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21165         dom_current=$(do_facet mds1 $LCTL get_param -n \
21166                                                 lod.$mdtname.dom_stripesize)
21167         [ 0 -eq ${dom_current} ] ||
21168                 error "Can't set zero DoM stripe limit"
21169         rm $dom
21170
21171         # attempt to create DoM file on server with disabled DoM should
21172         # remove DoM entry from layout and be succeed
21173         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21174                 error "Can't create DoM file (DoM is disabled)"
21175         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21176                 error "File has DoM component while DoM is disabled"
21177         rm $dom
21178
21179         # attempt to create DoM file with only DoM stripe should return error
21180         $LFS setstripe -E $dom_limit -L mdt $dom &&
21181                 error "Able to create DoM-only file while DoM is disabled"
21182
21183         # too low values to be aligned with smallest stripe size 64K
21184         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21185         dom_current=$(do_facet mds1 $LCTL get_param -n \
21186                                                 lod.$mdtname.dom_stripesize)
21187         [ 30000 -eq ${dom_current} ] &&
21188                 error "Can set too small DoM stripe limit"
21189
21190         # 64K is a minimal stripe size in Lustre, expect limit of that size
21191         [ 65536 -eq ${dom_current} ] ||
21192                 error "Limit is not set to 64K but ${dom_current}"
21193
21194         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21195         dom_current=$(do_facet mds1 $LCTL get_param -n \
21196                                                 lod.$mdtname.dom_stripesize)
21197         echo $dom_current
21198         [ 2147483648 -eq ${dom_current} ] &&
21199                 error "Can set too large DoM stripe limit"
21200
21201         do_facet mds1 $LCTL set_param -n \
21202                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21203         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21204                 error "Can't create DoM component size after limit change"
21205         do_facet mds1 $LCTL set_param -n \
21206                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21207         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21208                 error "Can't create DoM file after limit decrease"
21209         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21210                 error "Can create big DoM component after limit decrease"
21211         touch ${dom}_def ||
21212                 error "Can't create file with old default layout"
21213
21214         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21215         return 0
21216 }
21217 run_test 270f "DoM: maximum DoM stripe size checks"
21218
21219 test_270g() {
21220         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21221                 skip "Need MDS version at least 2.13.52"
21222         local dom=$DIR/$tdir/$tfile
21223
21224         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21225         local lodname=${FSNAME}-MDT0000-mdtlov
21226
21227         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21228         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21229         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21230         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21231
21232         local dom_limit=1024
21233         local dom_threshold="50%"
21234
21235         $LFS setstripe -d $DIR/$tdir
21236         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21237                 error "Can't set directory default striping"
21238
21239         do_facet mds1 $LCTL set_param -n \
21240                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21241         # set 0 threshold and create DOM file to change tunable stripesize
21242         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21243         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21244                 error "Failed to create $dom file"
21245         # now tunable dom_cur_stripesize should reach maximum
21246         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21247                                         lod.${lodname}.dom_stripesize_cur_kb)
21248         [[ $dom_current == $dom_limit ]] ||
21249                 error "Current DOM stripesize is not maximum"
21250         rm $dom
21251
21252         # set threshold for further tests
21253         do_facet mds1 $LCTL set_param -n \
21254                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21255         echo "DOM threshold is $dom_threshold free space"
21256         local dom_def
21257         local dom_set
21258         # Spoof bfree to exceed threshold
21259         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21260         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21261         for spfree in 40 20 0 15 30 55; do
21262                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21263                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21264                         error "Failed to create $dom file"
21265                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21266                                         lod.${lodname}.dom_stripesize_cur_kb)
21267                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21268                 [[ $dom_def != $dom_current ]] ||
21269                         error "Default stripe size was not changed"
21270                 if [[ $spfree > 0 ]] ; then
21271                         dom_set=$($LFS getstripe -S $dom)
21272                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21273                                 error "DOM component size is still old"
21274                 else
21275                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21276                                 error "DoM component is set with no free space"
21277                 fi
21278                 rm $dom
21279                 dom_current=$dom_def
21280         done
21281 }
21282 run_test 270g "DoM: default DoM stripe size depends on free space"
21283
21284 test_270h() {
21285         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21286                 skip "Need MDS version at least 2.13.53"
21287
21288         local mdtname=${FSNAME}-MDT0000-mdtlov
21289         local dom=$DIR/$tdir/$tfile
21290         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21291
21292         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21293         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21294
21295         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21296         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21297                 error "can't create OST file"
21298         # mirrored file with DOM entry in the second mirror
21299         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21300                 error "can't create mirror with DoM component"
21301
21302         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21303
21304         # DOM component in the middle and has other enries in the same mirror,
21305         # should succeed but lost DoM component
21306         $LFS setstripe --copy=${dom}_1 $dom ||
21307                 error "Can't create file from OST|DOM mirror layout"
21308         # check new file has no DoM layout after all
21309         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21310                 error "File has DoM component while DoM is disabled"
21311 }
21312 run_test 270h "DoM: DoM stripe removal when disabled on server"
21313
21314 test_271a() {
21315         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21316                 skip "Need MDS version at least 2.10.55"
21317
21318         local dom=$DIR/$tdir/dom
21319
21320         mkdir -p $DIR/$tdir
21321
21322         $LFS setstripe -E 1024K -L mdt $dom
21323
21324         lctl set_param -n mdc.*.stats=clear
21325         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21326         cat $dom > /dev/null
21327         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21328         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21329         ls $dom
21330         rm -f $dom
21331 }
21332 run_test 271a "DoM: data is cached for read after write"
21333
21334 test_271b() {
21335         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21336                 skip "Need MDS version at least 2.10.55"
21337
21338         local dom=$DIR/$tdir/dom
21339
21340         mkdir -p $DIR/$tdir
21341
21342         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21343
21344         lctl set_param -n mdc.*.stats=clear
21345         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21346         cancel_lru_locks mdc
21347         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21348         # second stat to check size is cached on client
21349         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21350         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21351         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21352         rm -f $dom
21353 }
21354 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21355
21356 test_271ba() {
21357         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21358                 skip "Need MDS version at least 2.10.55"
21359
21360         local dom=$DIR/$tdir/dom
21361
21362         mkdir -p $DIR/$tdir
21363
21364         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21365
21366         lctl set_param -n mdc.*.stats=clear
21367         lctl set_param -n osc.*.stats=clear
21368         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21369         cancel_lru_locks mdc
21370         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21371         # second stat to check size is cached on client
21372         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21373         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21374         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21375         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21376         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21377         rm -f $dom
21378 }
21379 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21380
21381
21382 get_mdc_stats() {
21383         local mdtidx=$1
21384         local param=$2
21385         local mdt=MDT$(printf %04x $mdtidx)
21386
21387         if [ -z $param ]; then
21388                 lctl get_param -n mdc.*$mdt*.stats
21389         else
21390                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21391         fi
21392 }
21393
21394 test_271c() {
21395         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21396                 skip "Need MDS version at least 2.10.55"
21397
21398         local dom=$DIR/$tdir/dom
21399
21400         mkdir -p $DIR/$tdir
21401
21402         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21403
21404         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21405         local facet=mds$((mdtidx + 1))
21406
21407         cancel_lru_locks mdc
21408         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21409         createmany -o $dom 1000
21410         lctl set_param -n mdc.*.stats=clear
21411         smalliomany -w $dom 1000 200
21412         get_mdc_stats $mdtidx
21413         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21414         # Each file has 1 open, 1 IO enqueues, total 2000
21415         # but now we have also +1 getxattr for security.capability, total 3000
21416         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21417         unlinkmany $dom 1000
21418
21419         cancel_lru_locks mdc
21420         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21421         createmany -o $dom 1000
21422         lctl set_param -n mdc.*.stats=clear
21423         smalliomany -w $dom 1000 200
21424         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21425         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21426         # for OPEN and IO lock.
21427         [ $((enq - enq_2)) -ge 1000 ] ||
21428                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21429         unlinkmany $dom 1000
21430         return 0
21431 }
21432 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21433
21434 cleanup_271def_tests() {
21435         trap 0
21436         rm -f $1
21437 }
21438
21439 test_271d() {
21440         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21441                 skip "Need MDS version at least 2.10.57"
21442
21443         local dom=$DIR/$tdir/dom
21444         local tmp=$TMP/$tfile
21445         trap "cleanup_271def_tests $tmp" EXIT
21446
21447         mkdir -p $DIR/$tdir
21448
21449         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21450
21451         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21452
21453         cancel_lru_locks mdc
21454         dd if=/dev/urandom of=$tmp bs=1000 count=1
21455         dd if=$tmp of=$dom bs=1000 count=1
21456         cancel_lru_locks mdc
21457
21458         cat /etc/hosts >> $tmp
21459         lctl set_param -n mdc.*.stats=clear
21460
21461         # append data to the same file it should update local page
21462         echo "Append to the same page"
21463         cat /etc/hosts >> $dom
21464         local num=$(get_mdc_stats $mdtidx ost_read)
21465         local ra=$(get_mdc_stats $mdtidx req_active)
21466         local rw=$(get_mdc_stats $mdtidx req_waittime)
21467
21468         [ -z $num ] || error "$num READ RPC occured"
21469         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21470         echo "... DONE"
21471
21472         # compare content
21473         cmp $tmp $dom || error "file miscompare"
21474
21475         cancel_lru_locks mdc
21476         lctl set_param -n mdc.*.stats=clear
21477
21478         echo "Open and read file"
21479         cat $dom > /dev/null
21480         local num=$(get_mdc_stats $mdtidx ost_read)
21481         local ra=$(get_mdc_stats $mdtidx req_active)
21482         local rw=$(get_mdc_stats $mdtidx req_waittime)
21483
21484         [ -z $num ] || error "$num READ RPC occured"
21485         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21486         echo "... DONE"
21487
21488         # compare content
21489         cmp $tmp $dom || error "file miscompare"
21490
21491         return 0
21492 }
21493 run_test 271d "DoM: read on open (1K file in reply buffer)"
21494
21495 test_271f() {
21496         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21497                 skip "Need MDS version at least 2.10.57"
21498
21499         local dom=$DIR/$tdir/dom
21500         local tmp=$TMP/$tfile
21501         trap "cleanup_271def_tests $tmp" EXIT
21502
21503         mkdir -p $DIR/$tdir
21504
21505         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21506
21507         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21508
21509         cancel_lru_locks mdc
21510         dd if=/dev/urandom of=$tmp bs=265000 count=1
21511         dd if=$tmp of=$dom bs=265000 count=1
21512         cancel_lru_locks mdc
21513         cat /etc/hosts >> $tmp
21514         lctl set_param -n mdc.*.stats=clear
21515
21516         echo "Append to the same page"
21517         cat /etc/hosts >> $dom
21518         local num=$(get_mdc_stats $mdtidx ost_read)
21519         local ra=$(get_mdc_stats $mdtidx req_active)
21520         local rw=$(get_mdc_stats $mdtidx req_waittime)
21521
21522         [ -z $num ] || error "$num READ RPC occured"
21523         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21524         echo "... DONE"
21525
21526         # compare content
21527         cmp $tmp $dom || error "file miscompare"
21528
21529         cancel_lru_locks mdc
21530         lctl set_param -n mdc.*.stats=clear
21531
21532         echo "Open and read file"
21533         cat $dom > /dev/null
21534         local num=$(get_mdc_stats $mdtidx ost_read)
21535         local ra=$(get_mdc_stats $mdtidx req_active)
21536         local rw=$(get_mdc_stats $mdtidx req_waittime)
21537
21538         [ -z $num ] && num=0
21539         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21540         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21541         echo "... DONE"
21542
21543         # compare content
21544         cmp $tmp $dom || error "file miscompare"
21545
21546         return 0
21547 }
21548 run_test 271f "DoM: read on open (200K file and read tail)"
21549
21550 test_271g() {
21551         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21552                 skip "Skipping due to old client or server version"
21553
21554         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21555         # to get layout
21556         $CHECKSTAT -t file $DIR1/$tfile
21557
21558         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21559         MULTIOP_PID=$!
21560         sleep 1
21561         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21562         $LCTL set_param fail_loc=0x80000314
21563         rm $DIR1/$tfile || error "Unlink fails"
21564         RC=$?
21565         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21566         [ $RC -eq 0 ] || error "Failed write to stale object"
21567 }
21568 run_test 271g "Discard DoM data vs client flush race"
21569
21570 test_272a() {
21571         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21572                 skip "Need MDS version at least 2.11.50"
21573
21574         local dom=$DIR/$tdir/dom
21575         mkdir -p $DIR/$tdir
21576
21577         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21578         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21579                 error "failed to write data into $dom"
21580         local old_md5=$(md5sum $dom)
21581
21582         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21583                 error "failed to migrate to the same DoM component"
21584
21585         local new_md5=$(md5sum $dom)
21586
21587         [ "$old_md5" == "$new_md5" ] ||
21588                 error "md5sum differ: $old_md5, $new_md5"
21589
21590         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21591                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21592 }
21593 run_test 272a "DoM migration: new layout with the same DOM component"
21594
21595 test_272b() {
21596         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21597                 skip "Need MDS version at least 2.11.50"
21598
21599         local dom=$DIR/$tdir/dom
21600         mkdir -p $DIR/$tdir
21601         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21602
21603         local mdtidx=$($LFS getstripe -m $dom)
21604         local mdtname=MDT$(printf %04x $mdtidx)
21605         local facet=mds$((mdtidx + 1))
21606
21607         local mdtfree1=$(do_facet $facet \
21608                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21609         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21610                 error "failed to write data into $dom"
21611         local old_md5=$(md5sum $dom)
21612         cancel_lru_locks mdc
21613         local mdtfree1=$(do_facet $facet \
21614                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21615
21616         $LFS migrate -c2 $dom ||
21617                 error "failed to migrate to the new composite layout"
21618         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21619                 error "MDT stripe was not removed"
21620
21621         cancel_lru_locks mdc
21622         local new_md5=$(md5sum $dom)
21623         [ "$old_md5" == "$new_md5" ] ||
21624                 error "$old_md5 != $new_md5"
21625
21626         # Skip free space checks with ZFS
21627         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21628                 local mdtfree2=$(do_facet $facet \
21629                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21630                 [ $mdtfree2 -gt $mdtfree1 ] ||
21631                         error "MDT space is not freed after migration"
21632         fi
21633         return 0
21634 }
21635 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21636
21637 test_272c() {
21638         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21639                 skip "Need MDS version at least 2.11.50"
21640
21641         local dom=$DIR/$tdir/$tfile
21642         mkdir -p $DIR/$tdir
21643         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21644
21645         local mdtidx=$($LFS getstripe -m $dom)
21646         local mdtname=MDT$(printf %04x $mdtidx)
21647         local facet=mds$((mdtidx + 1))
21648
21649         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21650                 error "failed to write data into $dom"
21651         local old_md5=$(md5sum $dom)
21652         cancel_lru_locks mdc
21653         local mdtfree1=$(do_facet $facet \
21654                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21655
21656         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21657                 error "failed to migrate to the new composite layout"
21658         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21659                 error "MDT stripe was not removed"
21660
21661         cancel_lru_locks mdc
21662         local new_md5=$(md5sum $dom)
21663         [ "$old_md5" == "$new_md5" ] ||
21664                 error "$old_md5 != $new_md5"
21665
21666         # Skip free space checks with ZFS
21667         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21668                 local mdtfree2=$(do_facet $facet \
21669                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21670                 [ $mdtfree2 -gt $mdtfree1 ] ||
21671                         error "MDS space is not freed after migration"
21672         fi
21673         return 0
21674 }
21675 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21676
21677 test_272d() {
21678         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21679                 skip "Need MDS version at least 2.12.55"
21680
21681         local dom=$DIR/$tdir/$tfile
21682         mkdir -p $DIR/$tdir
21683         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21684
21685         local mdtidx=$($LFS getstripe -m $dom)
21686         local mdtname=MDT$(printf %04x $mdtidx)
21687         local facet=mds$((mdtidx + 1))
21688
21689         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21690                 error "failed to write data into $dom"
21691         local old_md5=$(md5sum $dom)
21692         cancel_lru_locks mdc
21693         local mdtfree1=$(do_facet $facet \
21694                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21695
21696         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21697                 error "failed mirroring to the new composite layout"
21698         $LFS mirror resync $dom ||
21699                 error "failed mirror resync"
21700         $LFS mirror split --mirror-id 1 -d $dom ||
21701                 error "failed mirror split"
21702
21703         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21704                 error "MDT stripe was not removed"
21705
21706         cancel_lru_locks mdc
21707         local new_md5=$(md5sum $dom)
21708         [ "$old_md5" == "$new_md5" ] ||
21709                 error "$old_md5 != $new_md5"
21710
21711         # Skip free space checks with ZFS
21712         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21713                 local mdtfree2=$(do_facet $facet \
21714                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21715                 [ $mdtfree2 -gt $mdtfree1 ] ||
21716                         error "MDS space is not freed after DOM mirror deletion"
21717         fi
21718         return 0
21719 }
21720 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21721
21722 test_272e() {
21723         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21724                 skip "Need MDS version at least 2.12.55"
21725
21726         local dom=$DIR/$tdir/$tfile
21727         mkdir -p $DIR/$tdir
21728         $LFS setstripe -c 2 $dom
21729
21730         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21731                 error "failed to write data into $dom"
21732         local old_md5=$(md5sum $dom)
21733         cancel_lru_locks mdc
21734
21735         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21736                 error "failed mirroring to the DOM layout"
21737         $LFS mirror resync $dom ||
21738                 error "failed mirror resync"
21739         $LFS mirror split --mirror-id 1 -d $dom ||
21740                 error "failed mirror split"
21741
21742         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21743                 error "MDT stripe was not removed"
21744
21745         cancel_lru_locks mdc
21746         local new_md5=$(md5sum $dom)
21747         [ "$old_md5" == "$new_md5" ] ||
21748                 error "$old_md5 != $new_md5"
21749
21750         return 0
21751 }
21752 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21753
21754 test_272f() {
21755         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21756                 skip "Need MDS version at least 2.12.55"
21757
21758         local dom=$DIR/$tdir/$tfile
21759         mkdir -p $DIR/$tdir
21760         $LFS setstripe -c 2 $dom
21761
21762         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21763                 error "failed to write data into $dom"
21764         local old_md5=$(md5sum $dom)
21765         cancel_lru_locks mdc
21766
21767         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21768                 error "failed migrating to the DOM file"
21769
21770         cancel_lru_locks mdc
21771         local new_md5=$(md5sum $dom)
21772         [ "$old_md5" != "$new_md5" ] &&
21773                 error "$old_md5 != $new_md5"
21774
21775         return 0
21776 }
21777 run_test 272f "DoM migration: OST-striped file to DOM file"
21778
21779 test_273a() {
21780         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21781                 skip "Need MDS version at least 2.11.50"
21782
21783         # Layout swap cannot be done if either file has DOM component,
21784         # this will never be supported, migration should be used instead
21785
21786         local dom=$DIR/$tdir/$tfile
21787         mkdir -p $DIR/$tdir
21788
21789         $LFS setstripe -c2 ${dom}_plain
21790         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21791         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21792                 error "can swap layout with DoM component"
21793         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21794                 error "can swap layout with DoM component"
21795
21796         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21797         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21798                 error "can swap layout with DoM component"
21799         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21800                 error "can swap layout with DoM component"
21801         return 0
21802 }
21803 run_test 273a "DoM: layout swapping should fail with DOM"
21804
21805 test_273b() {
21806         mkdir -p $DIR/$tdir
21807         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21808
21809 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21810         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21811
21812         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21813 }
21814 run_test 273b "DoM: race writeback and object destroy"
21815
21816 test_275() {
21817         remote_ost_nodsh && skip "remote OST with nodsh"
21818         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21819                 skip "Need OST version >= 2.10.57"
21820
21821         local file=$DIR/$tfile
21822         local oss
21823
21824         oss=$(comma_list $(osts_nodes))
21825
21826         dd if=/dev/urandom of=$file bs=1M count=2 ||
21827                 error "failed to create a file"
21828         cancel_lru_locks osc
21829
21830         #lock 1
21831         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21832                 error "failed to read a file"
21833
21834 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21835         $LCTL set_param fail_loc=0x8000031f
21836
21837         cancel_lru_locks osc &
21838         sleep 1
21839
21840 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21841         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21842         #IO takes another lock, but matches the PENDING one
21843         #and places it to the IO RPC
21844         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21845                 error "failed to read a file with PENDING lock"
21846 }
21847 run_test 275 "Read on a canceled duplicate lock"
21848
21849 test_276() {
21850         remote_ost_nodsh && skip "remote OST with nodsh"
21851         local pid
21852
21853         do_facet ost1 "(while true; do \
21854                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21855                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21856         pid=$!
21857
21858         for LOOP in $(seq 20); do
21859                 stop ost1
21860                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21861         done
21862         kill -9 $pid
21863         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21864                 rm $TMP/sanity_276_pid"
21865 }
21866 run_test 276 "Race between mount and obd_statfs"
21867
21868 test_277() {
21869         $LCTL set_param ldlm.namespaces.*.lru_size=0
21870         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21871         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21872                         grep ^used_mb | awk '{print $2}')
21873         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21874         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21875                 oflag=direct conv=notrunc
21876         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21877                         grep ^used_mb | awk '{print $2}')
21878         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21879 }
21880 run_test 277 "Direct IO shall drop page cache"
21881
21882 test_278() {
21883         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21884         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21885         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21886                 skip "needs the same host for mdt1 mdt2" && return
21887
21888         local pid1
21889         local pid2
21890
21891 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21892         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21893         stop mds2 &
21894         pid2=$!
21895
21896         stop mds1
21897
21898         echo "Starting MDTs"
21899         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21900         wait $pid2
21901 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21902 #will return NULL
21903         do_facet mds2 $LCTL set_param fail_loc=0
21904
21905         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21906         wait_recovery_complete mds2
21907 }
21908 run_test 278 "Race starting MDS between MDTs stop/start"
21909
21910 test_280() {
21911         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21912                 skip "Need MGS version at least 2.13.52"
21913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21914         combined_mgs_mds || skip "needs combined MGS/MDT"
21915
21916         umount_client $MOUNT
21917 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21918         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21919
21920         mount_client $MOUNT &
21921         sleep 1
21922         stop mgs || error "stop mgs failed"
21923         #for a race mgs would crash
21924         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21925         # make sure we unmount client before remounting
21926         wait
21927         umount_client $MOUNT
21928         mount_client $MOUNT || error "mount client failed"
21929 }
21930 run_test 280 "Race between MGS umount and client llog processing"
21931
21932 cleanup_test_300() {
21933         trap 0
21934         umask $SAVE_UMASK
21935 }
21936 test_striped_dir() {
21937         local mdt_index=$1
21938         local stripe_count
21939         local stripe_index
21940
21941         mkdir -p $DIR/$tdir
21942
21943         SAVE_UMASK=$(umask)
21944         trap cleanup_test_300 RETURN EXIT
21945
21946         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21947                                                 $DIR/$tdir/striped_dir ||
21948                 error "set striped dir error"
21949
21950         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21951         [ "$mode" = "755" ] || error "expect 755 got $mode"
21952
21953         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21954                 error "getdirstripe failed"
21955         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21956         if [ "$stripe_count" != "2" ]; then
21957                 error "1:stripe_count is $stripe_count, expect 2"
21958         fi
21959         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21960         if [ "$stripe_count" != "2" ]; then
21961                 error "2:stripe_count is $stripe_count, expect 2"
21962         fi
21963
21964         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21965         if [ "$stripe_index" != "$mdt_index" ]; then
21966                 error "stripe_index is $stripe_index, expect $mdt_index"
21967         fi
21968
21969         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21970                 error "nlink error after create striped dir"
21971
21972         mkdir $DIR/$tdir/striped_dir/a
21973         mkdir $DIR/$tdir/striped_dir/b
21974
21975         stat $DIR/$tdir/striped_dir/a ||
21976                 error "create dir under striped dir failed"
21977         stat $DIR/$tdir/striped_dir/b ||
21978                 error "create dir under striped dir failed"
21979
21980         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21981                 error "nlink error after mkdir"
21982
21983         rmdir $DIR/$tdir/striped_dir/a
21984         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21985                 error "nlink error after rmdir"
21986
21987         rmdir $DIR/$tdir/striped_dir/b
21988         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21989                 error "nlink error after rmdir"
21990
21991         chattr +i $DIR/$tdir/striped_dir
21992         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21993                 error "immutable flags not working under striped dir!"
21994         chattr -i $DIR/$tdir/striped_dir
21995
21996         rmdir $DIR/$tdir/striped_dir ||
21997                 error "rmdir striped dir error"
21998
21999         cleanup_test_300
22000
22001         true
22002 }
22003
22004 test_300a() {
22005         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22006                 skip "skipped for lustre < 2.7.0"
22007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22009
22010         test_striped_dir 0 || error "failed on striped dir on MDT0"
22011         test_striped_dir 1 || error "failed on striped dir on MDT0"
22012 }
22013 run_test 300a "basic striped dir sanity test"
22014
22015 test_300b() {
22016         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22017                 skip "skipped for lustre < 2.7.0"
22018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22020
22021         local i
22022         local mtime1
22023         local mtime2
22024         local mtime3
22025
22026         test_mkdir $DIR/$tdir || error "mkdir fail"
22027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22028                 error "set striped dir error"
22029         for i in {0..9}; do
22030                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22031                 sleep 1
22032                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22033                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22034                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22035                 sleep 1
22036                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22037                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22038                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22039         done
22040         true
22041 }
22042 run_test 300b "check ctime/mtime for striped dir"
22043
22044 test_300c() {
22045         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22046                 skip "skipped for lustre < 2.7.0"
22047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22049
22050         local file_count
22051
22052         mkdir -p $DIR/$tdir
22053         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22054                 error "set striped dir error"
22055
22056         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22057                 error "chown striped dir failed"
22058
22059         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22060                 error "create 5k files failed"
22061
22062         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22063
22064         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22065
22066         rm -rf $DIR/$tdir
22067 }
22068 run_test 300c "chown && check ls under striped directory"
22069
22070 test_300d() {
22071         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22072                 skip "skipped for lustre < 2.7.0"
22073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22075
22076         local stripe_count
22077         local file
22078
22079         mkdir -p $DIR/$tdir
22080         $LFS setstripe -c 2 $DIR/$tdir
22081
22082         #local striped directory
22083         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22084                 error "set striped dir error"
22085         #look at the directories for debug purposes
22086         ls -l $DIR/$tdir
22087         $LFS getdirstripe $DIR/$tdir
22088         ls -l $DIR/$tdir/striped_dir
22089         $LFS getdirstripe $DIR/$tdir/striped_dir
22090         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22091                 error "create 10 files failed"
22092
22093         #remote striped directory
22094         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22095                 error "set striped dir error"
22096         #look at the directories for debug purposes
22097         ls -l $DIR/$tdir
22098         $LFS getdirstripe $DIR/$tdir
22099         ls -l $DIR/$tdir/remote_striped_dir
22100         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22101         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22102                 error "create 10 files failed"
22103
22104         for file in $(find $DIR/$tdir); do
22105                 stripe_count=$($LFS getstripe -c $file)
22106                 [ $stripe_count -eq 2 ] ||
22107                         error "wrong stripe $stripe_count for $file"
22108         done
22109
22110         rm -rf $DIR/$tdir
22111 }
22112 run_test 300d "check default stripe under striped directory"
22113
22114 test_300e() {
22115         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22116                 skip "Need MDS version at least 2.7.55"
22117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22119
22120         local stripe_count
22121         local file
22122
22123         mkdir -p $DIR/$tdir
22124
22125         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22126                 error "set striped dir error"
22127
22128         touch $DIR/$tdir/striped_dir/a
22129         touch $DIR/$tdir/striped_dir/b
22130         touch $DIR/$tdir/striped_dir/c
22131
22132         mkdir $DIR/$tdir/striped_dir/dir_a
22133         mkdir $DIR/$tdir/striped_dir/dir_b
22134         mkdir $DIR/$tdir/striped_dir/dir_c
22135
22136         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22137                 error "set striped adir under striped dir error"
22138
22139         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22140                 error "set striped bdir under striped dir error"
22141
22142         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22143                 error "set striped cdir under striped dir error"
22144
22145         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22146                 error "rename dir under striped dir fails"
22147
22148         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22149                 error "rename dir under different stripes fails"
22150
22151         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22152                 error "rename file under striped dir should succeed"
22153
22154         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22155                 error "rename dir under striped dir should succeed"
22156
22157         rm -rf $DIR/$tdir
22158 }
22159 run_test 300e "check rename under striped directory"
22160
22161 test_300f() {
22162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22164         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22165                 skip "Need MDS version at least 2.7.55"
22166
22167         local stripe_count
22168         local file
22169
22170         rm -rf $DIR/$tdir
22171         mkdir -p $DIR/$tdir
22172
22173         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22174                 error "set striped dir error"
22175
22176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22177                 error "set striped dir error"
22178
22179         touch $DIR/$tdir/striped_dir/a
22180         mkdir $DIR/$tdir/striped_dir/dir_a
22181         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22182                 error "create striped dir under striped dir fails"
22183
22184         touch $DIR/$tdir/striped_dir1/b
22185         mkdir $DIR/$tdir/striped_dir1/dir_b
22186         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22187                 error "create striped dir under striped dir fails"
22188
22189         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22190                 error "rename dir under different striped dir should fail"
22191
22192         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22193                 error "rename striped dir under diff striped dir should fail"
22194
22195         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22196                 error "rename file under diff striped dirs fails"
22197
22198         rm -rf $DIR/$tdir
22199 }
22200 run_test 300f "check rename cross striped directory"
22201
22202 test_300_check_default_striped_dir()
22203 {
22204         local dirname=$1
22205         local default_count=$2
22206         local default_index=$3
22207         local stripe_count
22208         local stripe_index
22209         local dir_stripe_index
22210         local dir
22211
22212         echo "checking $dirname $default_count $default_index"
22213         $LFS setdirstripe -D -c $default_count -i $default_index \
22214                                 -H all_char $DIR/$tdir/$dirname ||
22215                 error "set default stripe on striped dir error"
22216         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22217         [ $stripe_count -eq $default_count ] ||
22218                 error "expect $default_count get $stripe_count for $dirname"
22219
22220         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22221         [ $stripe_index -eq $default_index ] ||
22222                 error "expect $default_index get $stripe_index for $dirname"
22223
22224         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22225                                                 error "create dirs failed"
22226
22227         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22228         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22229         for dir in $(find $DIR/$tdir/$dirname/*); do
22230                 stripe_count=$($LFS getdirstripe -c $dir)
22231                 (( $stripe_count == $default_count )) ||
22232                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22233                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22234                 error "stripe count $default_count != $stripe_count for $dir"
22235
22236                 stripe_index=$($LFS getdirstripe -i $dir)
22237                 [ $default_index -eq -1 ] ||
22238                         [ $stripe_index -eq $default_index ] ||
22239                         error "$stripe_index != $default_index for $dir"
22240
22241                 #check default stripe
22242                 stripe_count=$($LFS getdirstripe -D -c $dir)
22243                 [ $stripe_count -eq $default_count ] ||
22244                 error "default count $default_count != $stripe_count for $dir"
22245
22246                 stripe_index=$($LFS getdirstripe -D -i $dir)
22247                 [ $stripe_index -eq $default_index ] ||
22248                 error "default index $default_index != $stripe_index for $dir"
22249         done
22250         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22251 }
22252
22253 test_300g() {
22254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22255         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22256                 skip "Need MDS version at least 2.7.55"
22257
22258         local dir
22259         local stripe_count
22260         local stripe_index
22261
22262         mkdir $DIR/$tdir
22263         mkdir $DIR/$tdir/normal_dir
22264
22265         #Checking when client cache stripe index
22266         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22267         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22268                 error "create striped_dir failed"
22269
22270         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22271                 error "create dir0 fails"
22272         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22273         [ $stripe_index -eq 0 ] ||
22274                 error "dir0 expect index 0 got $stripe_index"
22275
22276         mkdir $DIR/$tdir/striped_dir/dir1 ||
22277                 error "create dir1 fails"
22278         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22279         [ $stripe_index -eq 1 ] ||
22280                 error "dir1 expect index 1 got $stripe_index"
22281
22282         #check default stripe count/stripe index
22283         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22284         test_300_check_default_striped_dir normal_dir 1 0
22285         test_300_check_default_striped_dir normal_dir -1 1
22286         test_300_check_default_striped_dir normal_dir 2 -1
22287
22288         #delete default stripe information
22289         echo "delete default stripeEA"
22290         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22291                 error "set default stripe on striped dir error"
22292
22293         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22294         for dir in $(find $DIR/$tdir/normal_dir/*); do
22295                 stripe_count=$($LFS getdirstripe -c $dir)
22296                 [ $stripe_count -eq 0 ] ||
22297                         error "expect 1 get $stripe_count for $dir"
22298                 stripe_index=$($LFS getdirstripe -i $dir)
22299                 [ $stripe_index -eq 0 ] ||
22300                         error "expect 0 get $stripe_index for $dir"
22301         done
22302 }
22303 run_test 300g "check default striped directory for normal directory"
22304
22305 test_300h() {
22306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22308                 skip "Need MDS version at least 2.7.55"
22309
22310         local dir
22311         local stripe_count
22312
22313         mkdir $DIR/$tdir
22314         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22315                 error "set striped dir error"
22316
22317         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22318         test_300_check_default_striped_dir striped_dir 1 0
22319         test_300_check_default_striped_dir striped_dir -1 1
22320         test_300_check_default_striped_dir striped_dir 2 -1
22321
22322         #delete default stripe information
22323         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22324                 error "set default stripe on striped dir error"
22325
22326         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22327         for dir in $(find $DIR/$tdir/striped_dir/*); do
22328                 stripe_count=$($LFS getdirstripe -c $dir)
22329                 [ $stripe_count -eq 0 ] ||
22330                         error "expect 1 get $stripe_count for $dir"
22331         done
22332 }
22333 run_test 300h "check default striped directory for striped directory"
22334
22335 test_300i() {
22336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22338         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22339                 skip "Need MDS version at least 2.7.55"
22340
22341         local stripe_count
22342         local file
22343
22344         mkdir $DIR/$tdir
22345
22346         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22347                 error "set striped dir error"
22348
22349         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22350                 error "create files under striped dir failed"
22351
22352         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22353                 error "set striped hashdir error"
22354
22355         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22356                 error "create dir0 under hash dir failed"
22357         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22358                 error "create dir1 under hash dir failed"
22359         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22360                 error "create dir2 under hash dir failed"
22361
22362         # unfortunately, we need to umount to clear dir layout cache for now
22363         # once we fully implement dir layout, we can drop this
22364         umount_client $MOUNT || error "umount failed"
22365         mount_client $MOUNT || error "mount failed"
22366
22367         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22368         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22369         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22370
22371         #set the stripe to be unknown hash type
22372         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22373         $LCTL set_param fail_loc=0x1901
22374         for ((i = 0; i < 10; i++)); do
22375                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22376                         error "stat f-$i failed"
22377                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22378         done
22379
22380         touch $DIR/$tdir/striped_dir/f0 &&
22381                 error "create under striped dir with unknown hash should fail"
22382
22383         $LCTL set_param fail_loc=0
22384
22385         umount_client $MOUNT || error "umount failed"
22386         mount_client $MOUNT || error "mount failed"
22387
22388         return 0
22389 }
22390 run_test 300i "client handle unknown hash type striped directory"
22391
22392 test_300j() {
22393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22395         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22396                 skip "Need MDS version at least 2.7.55"
22397
22398         local stripe_count
22399         local file
22400
22401         mkdir $DIR/$tdir
22402
22403         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22404         $LCTL set_param fail_loc=0x1702
22405         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22406                 error "set striped dir error"
22407
22408         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22409                 error "create files under striped dir failed"
22410
22411         $LCTL set_param fail_loc=0
22412
22413         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22414
22415         return 0
22416 }
22417 run_test 300j "test large update record"
22418
22419 test_300k() {
22420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22422         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22423                 skip "Need MDS version at least 2.7.55"
22424
22425         # this test needs a huge transaction
22426         local kb
22427         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22428              osd*.$FSNAME-MDT0000.kbytestotal")
22429         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22430
22431         local stripe_count
22432         local file
22433
22434         mkdir $DIR/$tdir
22435
22436         #define OBD_FAIL_LARGE_STRIPE   0x1703
22437         $LCTL set_param fail_loc=0x1703
22438         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22439                 error "set striped dir error"
22440         $LCTL set_param fail_loc=0
22441
22442         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22443                 error "getstripeddir fails"
22444         rm -rf $DIR/$tdir/striped_dir ||
22445                 error "unlink striped dir fails"
22446
22447         return 0
22448 }
22449 run_test 300k "test large striped directory"
22450
22451 test_300l() {
22452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22454         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22455                 skip "Need MDS version at least 2.7.55"
22456
22457         local stripe_index
22458
22459         test_mkdir -p $DIR/$tdir/striped_dir
22460         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22461                         error "chown $RUNAS_ID failed"
22462         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22463                 error "set default striped dir failed"
22464
22465         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22466         $LCTL set_param fail_loc=0x80000158
22467         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22468
22469         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22470         [ $stripe_index -eq 1 ] ||
22471                 error "expect 1 get $stripe_index for $dir"
22472 }
22473 run_test 300l "non-root user to create dir under striped dir with stale layout"
22474
22475 test_300m() {
22476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22477         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22478         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22479                 skip "Need MDS version at least 2.7.55"
22480
22481         mkdir -p $DIR/$tdir/striped_dir
22482         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22483                 error "set default stripes dir error"
22484
22485         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22486
22487         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22488         [ $stripe_count -eq 0 ] ||
22489                         error "expect 0 get $stripe_count for a"
22490
22491         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22492                 error "set default stripes dir error"
22493
22494         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22495
22496         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22497         [ $stripe_count -eq 0 ] ||
22498                         error "expect 0 get $stripe_count for b"
22499
22500         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22501                 error "set default stripes dir error"
22502
22503         mkdir $DIR/$tdir/striped_dir/c &&
22504                 error "default stripe_index is invalid, mkdir c should fails"
22505
22506         rm -rf $DIR/$tdir || error "rmdir fails"
22507 }
22508 run_test 300m "setstriped directory on single MDT FS"
22509
22510 cleanup_300n() {
22511         local list=$(comma_list $(mdts_nodes))
22512
22513         trap 0
22514         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22515 }
22516
22517 test_300n() {
22518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22520         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22521                 skip "Need MDS version at least 2.7.55"
22522         remote_mds_nodsh && skip "remote MDS with nodsh"
22523
22524         local stripe_index
22525         local list=$(comma_list $(mdts_nodes))
22526
22527         trap cleanup_300n RETURN EXIT
22528         mkdir -p $DIR/$tdir
22529         chmod 777 $DIR/$tdir
22530         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22531                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22532                 error "create striped dir succeeds with gid=0"
22533
22534         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22535         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22536                 error "create striped dir fails with gid=-1"
22537
22538         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22539         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22540                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22541                 error "set default striped dir succeeds with gid=0"
22542
22543
22544         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22545         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22546                 error "set default striped dir fails with gid=-1"
22547
22548
22549         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22550         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22551                                         error "create test_dir fails"
22552         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22553                                         error "create test_dir1 fails"
22554         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22555                                         error "create test_dir2 fails"
22556         cleanup_300n
22557 }
22558 run_test 300n "non-root user to create dir under striped dir with default EA"
22559
22560 test_300o() {
22561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22563         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22564                 skip "Need MDS version at least 2.7.55"
22565
22566         local numfree1
22567         local numfree2
22568
22569         mkdir -p $DIR/$tdir
22570
22571         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22572         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22573         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22574                 skip "not enough free inodes $numfree1 $numfree2"
22575         fi
22576
22577         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22578         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22579         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22580                 skip "not enough free space $numfree1 $numfree2"
22581         fi
22582
22583         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22584                 error "setdirstripe fails"
22585
22586         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22587                 error "create dirs fails"
22588
22589         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22590         ls $DIR/$tdir/striped_dir > /dev/null ||
22591                 error "ls striped dir fails"
22592         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22593                 error "unlink big striped dir fails"
22594 }
22595 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22596
22597 test_300p() {
22598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22600         remote_mds_nodsh && skip "remote MDS with nodsh"
22601
22602         mkdir -p $DIR/$tdir
22603
22604         #define OBD_FAIL_OUT_ENOSPC     0x1704
22605         do_facet mds2 lctl set_param fail_loc=0x80001704
22606         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22607                  && error "create striped directory should fail"
22608
22609         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22610
22611         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22612         true
22613 }
22614 run_test 300p "create striped directory without space"
22615
22616 test_300q() {
22617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22619
22620         local fd=$(free_fd)
22621         local cmd="exec $fd<$tdir"
22622         cd $DIR
22623         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22624         eval $cmd
22625         cmd="exec $fd<&-"
22626         trap "eval $cmd" EXIT
22627         cd $tdir || error "cd $tdir fails"
22628         rmdir  ../$tdir || error "rmdir $tdir fails"
22629         mkdir local_dir && error "create dir succeeds"
22630         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22631         eval $cmd
22632         return 0
22633 }
22634 run_test 300q "create remote directory under orphan directory"
22635
22636 test_300r() {
22637         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22638                 skip "Need MDS version at least 2.7.55" && return
22639         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22640
22641         mkdir $DIR/$tdir
22642
22643         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22644                 error "set striped dir error"
22645
22646         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22647                 error "getstripeddir fails"
22648
22649         local stripe_count
22650         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22651                       awk '/lmv_stripe_count:/ { print $2 }')
22652
22653         [ $MDSCOUNT -ne $stripe_count ] &&
22654                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22655
22656         rm -rf $DIR/$tdir/striped_dir ||
22657                 error "unlink striped dir fails"
22658 }
22659 run_test 300r "test -1 striped directory"
22660
22661 test_300s_helper() {
22662         local count=$1
22663
22664         local stripe_dir=$DIR/$tdir/striped_dir.$count
22665
22666         $LFS mkdir -c $count $stripe_dir ||
22667                 error "lfs mkdir -c error"
22668
22669         $LFS getdirstripe $stripe_dir ||
22670                 error "lfs getdirstripe fails"
22671
22672         local stripe_count
22673         stripe_count=$($LFS getdirstripe $stripe_dir |
22674                       awk '/lmv_stripe_count:/ { print $2 }')
22675
22676         [ $count -ne $stripe_count ] &&
22677                 error_noexit "bad stripe count $stripe_count expected $count"
22678
22679         local dupe_stripes
22680         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22681                 awk '/0x/ {count[$1] += 1}; END {
22682                         for (idx in count) {
22683                                 if (count[idx]>1) {
22684                                         print "index " idx " count " count[idx]
22685                                 }
22686                         }
22687                 }')
22688
22689         if [[ -n "$dupe_stripes" ]] ; then
22690                 lfs getdirstripe $stripe_dir
22691                 error_noexit "Dupe MDT above: $dupe_stripes "
22692         fi
22693
22694         rm -rf $stripe_dir ||
22695                 error_noexit "unlink $stripe_dir fails"
22696 }
22697
22698 test_300s() {
22699         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22700                 skip "Need MDS version at least 2.7.55" && return
22701         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22702
22703         mkdir $DIR/$tdir
22704         for count in $(seq 2 $MDSCOUNT); do
22705                 test_300s_helper $count
22706         done
22707 }
22708 run_test 300s "test lfs mkdir -c without -i"
22709
22710
22711 prepare_remote_file() {
22712         mkdir $DIR/$tdir/src_dir ||
22713                 error "create remote source failed"
22714
22715         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22716                  error "cp to remote source failed"
22717         touch $DIR/$tdir/src_dir/a
22718
22719         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22720                 error "create remote target dir failed"
22721
22722         touch $DIR/$tdir/tgt_dir/b
22723
22724         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22725                 error "rename dir cross MDT failed!"
22726
22727         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22728                 error "src_child still exists after rename"
22729
22730         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22731                 error "missing file(a) after rename"
22732
22733         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22734                 error "diff after rename"
22735 }
22736
22737 test_310a() {
22738         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22740
22741         local remote_file=$DIR/$tdir/tgt_dir/b
22742
22743         mkdir -p $DIR/$tdir
22744
22745         prepare_remote_file || error "prepare remote file failed"
22746
22747         #open-unlink file
22748         $OPENUNLINK $remote_file $remote_file ||
22749                 error "openunlink $remote_file failed"
22750         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22751 }
22752 run_test 310a "open unlink remote file"
22753
22754 test_310b() {
22755         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22757
22758         local remote_file=$DIR/$tdir/tgt_dir/b
22759
22760         mkdir -p $DIR/$tdir
22761
22762         prepare_remote_file || error "prepare remote file failed"
22763
22764         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22765         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22766         $CHECKSTAT -t file $remote_file || error "check file failed"
22767 }
22768 run_test 310b "unlink remote file with multiple links while open"
22769
22770 test_310c() {
22771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22772         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22773
22774         local remote_file=$DIR/$tdir/tgt_dir/b
22775
22776         mkdir -p $DIR/$tdir
22777
22778         prepare_remote_file || error "prepare remote file failed"
22779
22780         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22781         multiop_bg_pause $remote_file O_uc ||
22782                         error "mulitop failed for remote file"
22783         MULTIPID=$!
22784         $MULTIOP $DIR/$tfile Ouc
22785         kill -USR1 $MULTIPID
22786         wait $MULTIPID
22787 }
22788 run_test 310c "open-unlink remote file with multiple links"
22789
22790 #LU-4825
22791 test_311() {
22792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22793         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22794         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22795                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22796         remote_mds_nodsh && skip "remote MDS with nodsh"
22797
22798         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22799         local mdts=$(comma_list $(mdts_nodes))
22800
22801         mkdir -p $DIR/$tdir
22802         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22803         createmany -o $DIR/$tdir/$tfile. 1000
22804
22805         # statfs data is not real time, let's just calculate it
22806         old_iused=$((old_iused + 1000))
22807
22808         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22809                         osp.*OST0000*MDT0000.create_count")
22810         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22811                                 osp.*OST0000*MDT0000.max_create_count")
22812         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22813
22814         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22815         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22816         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22817
22818         unlinkmany $DIR/$tdir/$tfile. 1000
22819
22820         do_nodes $mdts "$LCTL set_param -n \
22821                         osp.*OST0000*.max_create_count=$max_count"
22822         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22823                 do_nodes $mdts "$LCTL set_param -n \
22824                                 osp.*OST0000*.create_count=$count"
22825         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22826                         grep "=0" && error "create_count is zero"
22827
22828         local new_iused
22829         for i in $(seq 120); do
22830                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22831                 # system may be too busy to destroy all objs in time, use
22832                 # a somewhat small value to not fail autotest
22833                 [ $((old_iused - new_iused)) -gt 400 ] && break
22834                 sleep 1
22835         done
22836
22837         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22838         [ $((old_iused - new_iused)) -gt 400 ] ||
22839                 error "objs not destroyed after unlink"
22840 }
22841 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22842
22843 zfs_oid_to_objid()
22844 {
22845         local ost=$1
22846         local objid=$2
22847
22848         local vdevdir=$(dirname $(facet_vdevice $ost))
22849         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22850         local zfs_zapid=$(do_facet $ost $cmd |
22851                           grep -w "/O/0/d$((objid%32))" -C 5 |
22852                           awk '/Object/{getline; print $1}')
22853         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22854                           awk "/$objid = /"'{printf $3}')
22855
22856         echo $zfs_objid
22857 }
22858
22859 zfs_object_blksz() {
22860         local ost=$1
22861         local objid=$2
22862
22863         local vdevdir=$(dirname $(facet_vdevice $ost))
22864         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22865         local blksz=$(do_facet $ost $cmd $objid |
22866                       awk '/dblk/{getline; printf $4}')
22867
22868         case "${blksz: -1}" in
22869                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22870                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22871                 *) ;;
22872         esac
22873
22874         echo $blksz
22875 }
22876
22877 test_312() { # LU-4856
22878         remote_ost_nodsh && skip "remote OST with nodsh"
22879         [ "$ost1_FSTYPE" = "zfs" ] ||
22880                 skip_env "the test only applies to zfs"
22881
22882         local max_blksz=$(do_facet ost1 \
22883                           $ZFS get -p recordsize $(facet_device ost1) |
22884                           awk '!/VALUE/{print $3}')
22885
22886         # to make life a little bit easier
22887         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22888         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22889
22890         local tf=$DIR/$tdir/$tfile
22891         touch $tf
22892         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22893
22894         # Get ZFS object id
22895         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22896         # block size change by sequential overwrite
22897         local bs
22898
22899         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22900                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22901
22902                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22903                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22904         done
22905         rm -f $tf
22906
22907         # block size change by sequential append write
22908         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22909         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22910         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22911         local count
22912
22913         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22914                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22915                         oflag=sync conv=notrunc
22916
22917                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22918                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22919                         error "blksz error, actual $blksz, " \
22920                                 "expected: 2 * $count * $PAGE_SIZE"
22921         done
22922         rm -f $tf
22923
22924         # random write
22925         touch $tf
22926         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22927         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22928
22929         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22930         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22931         [ $blksz -eq $PAGE_SIZE ] ||
22932                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22933
22934         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22935         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22936         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22937
22938         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22939         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22940         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22941 }
22942 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22943
22944 test_313() {
22945         remote_ost_nodsh && skip "remote OST with nodsh"
22946
22947         local file=$DIR/$tfile
22948
22949         rm -f $file
22950         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22951
22952         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22953         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22954         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22955                 error "write should failed"
22956         do_facet ost1 "$LCTL set_param fail_loc=0"
22957         rm -f $file
22958 }
22959 run_test 313 "io should fail after last_rcvd update fail"
22960
22961 test_314() {
22962         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22963
22964         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22965         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22966         rm -f $DIR/$tfile
22967         wait_delete_completed
22968         do_facet ost1 "$LCTL set_param fail_loc=0"
22969 }
22970 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22971
22972 test_315() { # LU-618
22973         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22974
22975         local file=$DIR/$tfile
22976         rm -f $file
22977
22978         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22979                 error "multiop file write failed"
22980         $MULTIOP $file oO_RDONLY:r4063232_c &
22981         PID=$!
22982
22983         sleep 2
22984
22985         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22986         kill -USR1 $PID
22987
22988         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22989         rm -f $file
22990 }
22991 run_test 315 "read should be accounted"
22992
22993 test_316() {
22994         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22995         large_xattr_enabled || skip_env "ea_inode feature disabled"
22996
22997         rm -rf $DIR/$tdir/d
22998         mkdir -p $DIR/$tdir/d
22999         chown nobody $DIR/$tdir/d
23000         touch $DIR/$tdir/d/file
23001
23002         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23003 }
23004 run_test 316 "lfs mv"
23005
23006 test_317() {
23007         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23008                 skip "Need MDS version at least 2.11.53"
23009         if [ "$ost1_FSTYPE" == "zfs" ]; then
23010                 skip "LU-10370: no implementation for ZFS"
23011         fi
23012
23013         local trunc_sz
23014         local grant_blk_size
23015
23016         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23017                         awk '/grant_block_size:/ { print $2; exit; }')
23018         #
23019         # Create File of size 5M. Truncate it to below size's and verify
23020         # blocks count.
23021         #
23022         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23023                 error "Create file $DIR/$tfile failed"
23024         stack_trap "rm -f $DIR/$tfile" EXIT
23025
23026         for trunc_sz in 2097152 4097 4000 509 0; do
23027                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23028                         error "truncate $tfile to $trunc_sz failed"
23029                 local sz=$(stat --format=%s $DIR/$tfile)
23030                 local blk=$(stat --format=%b $DIR/$tfile)
23031                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23032                                      grant_blk_size) * 8))
23033
23034                 if [[ $blk -ne $trunc_blk ]]; then
23035                         $(which stat) $DIR/$tfile
23036                         error "Expected Block $trunc_blk got $blk for $tfile"
23037                 fi
23038
23039                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23040                         error "Expected Size $trunc_sz got $sz for $tfile"
23041         done
23042
23043         #
23044         # sparse file test
23045         # Create file with a hole and write actual two blocks. Block count
23046         # must be 16.
23047         #
23048         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23049                 conv=fsync || error "Create file : $DIR/$tfile"
23050
23051         # Calculate the final truncate size.
23052         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23053
23054         #
23055         # truncate to size $trunc_sz bytes. Strip the last block
23056         # The block count must drop to 8
23057         #
23058         $TRUNCATE $DIR/$tfile $trunc_sz ||
23059                 error "truncate $tfile to $trunc_sz failed"
23060
23061         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23062         sz=$(stat --format=%s $DIR/$tfile)
23063         blk=$(stat --format=%b $DIR/$tfile)
23064
23065         if [[ $blk -ne $trunc_bsz ]]; then
23066                 $(which stat) $DIR/$tfile
23067                 error "Expected Block $trunc_bsz got $blk for $tfile"
23068         fi
23069
23070         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23071                 error "Expected Size $trunc_sz got $sz for $tfile"
23072 }
23073 run_test 317 "Verify blocks get correctly update after truncate"
23074
23075 test_318() {
23076         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23077         local old_max_active=$($LCTL get_param -n \
23078                             ${llite_name}.max_read_ahead_async_active \
23079                             2>/dev/null)
23080
23081         $LCTL set_param llite.*.max_read_ahead_async_active=256
23082         local max_active=$($LCTL get_param -n \
23083                            ${llite_name}.max_read_ahead_async_active \
23084                            2>/dev/null)
23085         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23086
23087         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23088                 error "set max_read_ahead_async_active should succeed"
23089
23090         $LCTL set_param llite.*.max_read_ahead_async_active=512
23091         max_active=$($LCTL get_param -n \
23092                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23093         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23094
23095         # restore @max_active
23096         [ $old_max_active -ne 0 ] && $LCTL set_param \
23097                 llite.*.max_read_ahead_async_active=$old_max_active
23098
23099         local old_threshold=$($LCTL get_param -n \
23100                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23101         local max_per_file_mb=$($LCTL get_param -n \
23102                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23103
23104         local invalid=$(($max_per_file_mb + 1))
23105         $LCTL set_param \
23106                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23107                         && error "set $invalid should fail"
23108
23109         local valid=$(($invalid - 1))
23110         $LCTL set_param \
23111                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23112                         error "set $valid should succeed"
23113         local threshold=$($LCTL get_param -n \
23114                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23115         [ $threshold -eq $valid ] || error \
23116                 "expect threshold $valid got $threshold"
23117         $LCTL set_param \
23118                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23119 }
23120 run_test 318 "Verify async readahead tunables"
23121
23122 test_319() {
23123         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23124
23125         local before=$(date +%s)
23126         local evict
23127         local mdir=$DIR/$tdir
23128         local file=$mdir/xxx
23129
23130         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23131         touch $file
23132
23133 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23134         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23135         $LFS mv -m1 $file &
23136
23137         sleep 1
23138         dd if=$file of=/dev/null
23139         wait
23140         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23141           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23142
23143         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23144 }
23145 run_test 319 "lost lease lock on migrate error"
23146
23147 test_398a() { # LU-4198
23148         local ost1_imp=$(get_osc_import_name client ost1)
23149         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23150                          cut -d'.' -f2)
23151
23152         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23153         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23154
23155         # request a new lock on client
23156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23157
23158         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23159         local lock_count=$($LCTL get_param -n \
23160                            ldlm.namespaces.$imp_name.lru_size)
23161         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23162
23163         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23164
23165         # no lock cached, should use lockless IO and not enqueue new lock
23166         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23167         lock_count=$($LCTL get_param -n \
23168                      ldlm.namespaces.$imp_name.lru_size)
23169         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23170 }
23171 run_test 398a "direct IO should cancel lock otherwise lockless"
23172
23173 test_398b() { # LU-4198
23174         which fio || skip_env "no fio installed"
23175         $LFS setstripe -c -1 $DIR/$tfile
23176
23177         local size=12
23178         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23179
23180         local njobs=4
23181         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23182         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23183                 --numjobs=$njobs --fallocate=none \
23184                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23185                 --filename=$DIR/$tfile &
23186         bg_pid=$!
23187
23188         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23189         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23190                 --numjobs=$njobs --fallocate=none \
23191                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23192                 --filename=$DIR/$tfile || true
23193         wait $bg_pid
23194
23195         rm -rf $DIR/$tfile
23196 }
23197 run_test 398b "DIO and buffer IO race"
23198
23199 test_398c() { # LU-4198
23200         local ost1_imp=$(get_osc_import_name client ost1)
23201         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23202                          cut -d'.' -f2)
23203
23204         which fio || skip_env "no fio installed"
23205
23206         saved_debug=$($LCTL get_param -n debug)
23207         $LCTL set_param debug=0
23208
23209         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23210         ((size /= 1024)) # by megabytes
23211         ((size /= 2)) # write half of the OST at most
23212         [ $size -gt 40 ] && size=40 #reduce test time anyway
23213
23214         $LFS setstripe -c 1 $DIR/$tfile
23215
23216         # it seems like ldiskfs reserves more space than necessary if the
23217         # writing blocks are not mapped, so it extends the file firstly
23218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23219         cancel_lru_locks osc
23220
23221         # clear and verify rpc_stats later
23222         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23223
23224         local njobs=4
23225         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23226         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23227                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23228                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23229                 --filename=$DIR/$tfile
23230         [ $? -eq 0 ] || error "fio write error"
23231
23232         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23233                 error "Locks were requested while doing AIO"
23234
23235         # get the percentage of 1-page I/O
23236         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23237                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23238                 awk '{print $7}')
23239         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23240
23241         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23242         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23243                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23244                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23245                 --filename=$DIR/$tfile
23246         [ $? -eq 0 ] || error "fio mixed read write error"
23247
23248         echo "AIO with large block size ${size}M"
23249         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23250                 --numjobs=1 --fallocate=none --ioengine=libaio \
23251                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23252                 --filename=$DIR/$tfile
23253         [ $? -eq 0 ] || error "fio large block size failed"
23254
23255         rm -rf $DIR/$tfile
23256         $LCTL set_param debug="$saved_debug"
23257 }
23258 run_test 398c "run fio to test AIO"
23259
23260 test_398d() { #  LU-13846
23261         test -f aiocp || skip_env "no aiocp installed"
23262         local aio_file=$DIR/aio_file
23263
23264         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23265
23266         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23267         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23268
23269         diff $DIR/$tfile $aio_file || "file diff after aiocp"
23270
23271         # make sure we don't crash and fail properly
23272         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23273                 error "aio not aligned with PAGE SIZE should fail"
23274
23275         rm -rf $DIR/$tfile $aio_file
23276 }
23277 run_test 398d "run aiocp to verify block size > stripe size"
23278
23279 test_398e() {
23280         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23281         touch $DIR/$tfile.new
23282         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23283 }
23284 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23285
23286 test_fake_rw() {
23287         local read_write=$1
23288         if [ "$read_write" = "write" ]; then
23289                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23290         elif [ "$read_write" = "read" ]; then
23291                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23292         else
23293                 error "argument error"
23294         fi
23295
23296         # turn off debug for performance testing
23297         local saved_debug=$($LCTL get_param -n debug)
23298         $LCTL set_param debug=0
23299
23300         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23301
23302         # get ost1 size - $FSNAME-OST0000
23303         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23304         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23305         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23306
23307         if [ "$read_write" = "read" ]; then
23308                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23309         fi
23310
23311         local start_time=$(date +%s.%N)
23312         $dd_cmd bs=1M count=$blocks oflag=sync ||
23313                 error "real dd $read_write error"
23314         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23315
23316         if [ "$read_write" = "write" ]; then
23317                 rm -f $DIR/$tfile
23318         fi
23319
23320         # define OBD_FAIL_OST_FAKE_RW           0x238
23321         do_facet ost1 $LCTL set_param fail_loc=0x238
23322
23323         local start_time=$(date +%s.%N)
23324         $dd_cmd bs=1M count=$blocks oflag=sync ||
23325                 error "fake dd $read_write error"
23326         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23327
23328         if [ "$read_write" = "write" ]; then
23329                 # verify file size
23330                 cancel_lru_locks osc
23331                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23332                         error "$tfile size not $blocks MB"
23333         fi
23334         do_facet ost1 $LCTL set_param fail_loc=0
23335
23336         echo "fake $read_write $duration_fake vs. normal $read_write" \
23337                 "$duration in seconds"
23338         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23339                 error_not_in_vm "fake write is slower"
23340
23341         $LCTL set_param -n debug="$saved_debug"
23342         rm -f $DIR/$tfile
23343 }
23344 test_399a() { # LU-7655 for OST fake write
23345         remote_ost_nodsh && skip "remote OST with nodsh"
23346
23347         test_fake_rw write
23348 }
23349 run_test 399a "fake write should not be slower than normal write"
23350
23351 test_399b() { # LU-8726 for OST fake read
23352         remote_ost_nodsh && skip "remote OST with nodsh"
23353         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23354                 skip_env "ldiskfs only test"
23355         fi
23356
23357         test_fake_rw read
23358 }
23359 run_test 399b "fake read should not be slower than normal read"
23360
23361 test_400a() { # LU-1606, was conf-sanity test_74
23362         if ! which $CC > /dev/null 2>&1; then
23363                 skip_env "$CC is not installed"
23364         fi
23365
23366         local extra_flags=''
23367         local out=$TMP/$tfile
23368         local prefix=/usr/include/lustre
23369         local prog
23370
23371         # Oleg removes c files in his test rig so test if any c files exist
23372         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23373                 skip_env "Needed c test files are missing"
23374
23375         if ! [[ -d $prefix ]]; then
23376                 # Assume we're running in tree and fixup the include path.
23377                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23378                 extra_flags+=" -L$LUSTRE/utils/.lib"
23379         fi
23380
23381         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23382                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23383                         error "client api broken"
23384         done
23385         rm -f $out
23386 }
23387 run_test 400a "Lustre client api program can compile and link"
23388
23389 test_400b() { # LU-1606, LU-5011
23390         local header
23391         local out=$TMP/$tfile
23392         local prefix=/usr/include/linux/lustre
23393
23394         # We use a hard coded prefix so that this test will not fail
23395         # when run in tree. There are headers in lustre/include/lustre/
23396         # that are not packaged (like lustre_idl.h) and have more
23397         # complicated include dependencies (like config.h and lnet/types.h).
23398         # Since this test about correct packaging we just skip them when
23399         # they don't exist (see below) rather than try to fixup cppflags.
23400
23401         if ! which $CC > /dev/null 2>&1; then
23402                 skip_env "$CC is not installed"
23403         fi
23404
23405         for header in $prefix/*.h; do
23406                 if ! [[ -f "$header" ]]; then
23407                         continue
23408                 fi
23409
23410                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23411                         continue # lustre_ioctl.h is internal header
23412                 fi
23413
23414                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23415                         error "cannot compile '$header'"
23416         done
23417         rm -f $out
23418 }
23419 run_test 400b "packaged headers can be compiled"
23420
23421 test_401a() { #LU-7437
23422         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23423         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23424
23425         #count the number of parameters by "list_param -R"
23426         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23427         #count the number of parameters by listing proc files
23428         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23429         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23430         echo "proc_dirs='$proc_dirs'"
23431         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23432         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23433                       sort -u | wc -l)
23434
23435         [ $params -eq $procs ] ||
23436                 error "found $params parameters vs. $procs proc files"
23437
23438         # test the list_param -D option only returns directories
23439         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23440         #count the number of parameters by listing proc directories
23441         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23442                 sort -u | wc -l)
23443
23444         [ $params -eq $procs ] ||
23445                 error "found $params parameters vs. $procs proc files"
23446 }
23447 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23448
23449 test_401b() {
23450         # jobid_var may not allow arbitrary values, so use jobid_name
23451         # if available
23452         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23453                 local testname=jobid_name tmp='testing%p'
23454         else
23455                 local testname=jobid_var tmp=testing
23456         fi
23457
23458         local save=$($LCTL get_param -n $testname)
23459
23460         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23461                 error "no error returned when setting bad parameters"
23462
23463         local jobid_new=$($LCTL get_param -n foe $testname baz)
23464         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23465
23466         $LCTL set_param -n fog=bam $testname=$save bat=fog
23467         local jobid_old=$($LCTL get_param -n foe $testname bag)
23468         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23469 }
23470 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23471
23472 test_401c() {
23473         # jobid_var may not allow arbitrary values, so use jobid_name
23474         # if available
23475         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23476                 local testname=jobid_name
23477         else
23478                 local testname=jobid_var
23479         fi
23480
23481         local jobid_var_old=$($LCTL get_param -n $testname)
23482         local jobid_var_new
23483
23484         $LCTL set_param $testname= &&
23485                 error "no error returned for 'set_param a='"
23486
23487         jobid_var_new=$($LCTL get_param -n $testname)
23488         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23489                 error "$testname was changed by setting without value"
23490
23491         $LCTL set_param $testname &&
23492                 error "no error returned for 'set_param a'"
23493
23494         jobid_var_new=$($LCTL get_param -n $testname)
23495         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23496                 error "$testname was changed by setting without value"
23497 }
23498 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23499
23500 test_401d() {
23501         # jobid_var may not allow arbitrary values, so use jobid_name
23502         # if available
23503         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23504                 local testname=jobid_name new_value='foo=bar%p'
23505         else
23506                 local testname=jobid_var new_valuie=foo=bar
23507         fi
23508
23509         local jobid_var_old=$($LCTL get_param -n $testname)
23510         local jobid_var_new
23511
23512         $LCTL set_param $testname=$new_value ||
23513                 error "'set_param a=b' did not accept a value containing '='"
23514
23515         jobid_var_new=$($LCTL get_param -n $testname)
23516         [[ "$jobid_var_new" == "$new_value" ]] ||
23517                 error "'set_param a=b' failed on a value containing '='"
23518
23519         # Reset the $testname to test the other format
23520         $LCTL set_param $testname=$jobid_var_old
23521         jobid_var_new=$($LCTL get_param -n $testname)
23522         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23523                 error "failed to reset $testname"
23524
23525         $LCTL set_param $testname $new_value ||
23526                 error "'set_param a b' did not accept a value containing '='"
23527
23528         jobid_var_new=$($LCTL get_param -n $testname)
23529         [[ "$jobid_var_new" == "$new_value" ]] ||
23530                 error "'set_param a b' failed on a value containing '='"
23531
23532         $LCTL set_param $testname $jobid_var_old
23533         jobid_var_new=$($LCTL get_param -n $testname)
23534         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23535                 error "failed to reset $testname"
23536 }
23537 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23538
23539 test_402() {
23540         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23541         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23542                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23543         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23544                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23545                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23546         remote_mds_nodsh && skip "remote MDS with nodsh"
23547
23548         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23549 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23550         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23551         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23552                 echo "Touch failed - OK"
23553 }
23554 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23555
23556 test_403() {
23557         local file1=$DIR/$tfile.1
23558         local file2=$DIR/$tfile.2
23559         local tfile=$TMP/$tfile
23560
23561         rm -f $file1 $file2 $tfile
23562
23563         touch $file1
23564         ln $file1 $file2
23565
23566         # 30 sec OBD_TIMEOUT in ll_getattr()
23567         # right before populating st_nlink
23568         $LCTL set_param fail_loc=0x80001409
23569         stat -c %h $file1 > $tfile &
23570
23571         # create an alias, drop all locks and reclaim the dentry
23572         < $file2
23573         cancel_lru_locks mdc
23574         cancel_lru_locks osc
23575         sysctl -w vm.drop_caches=2
23576
23577         wait
23578
23579         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23580
23581         rm -f $tfile $file1 $file2
23582 }
23583 run_test 403 "i_nlink should not drop to zero due to aliasing"
23584
23585 test_404() { # LU-6601
23586         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23587                 skip "Need server version newer than 2.8.52"
23588         remote_mds_nodsh && skip "remote MDS with nodsh"
23589
23590         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23591                 awk '/osp .*-osc-MDT/ { print $4}')
23592
23593         local osp
23594         for osp in $mosps; do
23595                 echo "Deactivate: " $osp
23596                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23597                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23598                         awk -vp=$osp '$4 == p { print $2 }')
23599                 [ $stat = IN ] || {
23600                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23601                         error "deactivate error"
23602                 }
23603                 echo "Activate: " $osp
23604                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23605                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23606                         awk -vp=$osp '$4 == p { print $2 }')
23607                 [ $stat = UP ] || {
23608                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23609                         error "activate error"
23610                 }
23611         done
23612 }
23613 run_test 404 "validate manual {de}activated works properly for OSPs"
23614
23615 test_405() {
23616         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23617         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23618                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23619                         skip "Layout swap lock is not supported"
23620
23621         check_swap_layouts_support
23622         check_swap_layout_no_dom $DIR
23623
23624         test_mkdir $DIR/$tdir
23625         swap_lock_test -d $DIR/$tdir ||
23626                 error "One layout swap locked test failed"
23627 }
23628 run_test 405 "Various layout swap lock tests"
23629
23630 test_406() {
23631         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23632         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23633         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23635         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23636                 skip "Need MDS version at least 2.8.50"
23637
23638         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23639         local test_pool=$TESTNAME
23640
23641         pool_add $test_pool || error "pool_add failed"
23642         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23643                 error "pool_add_targets failed"
23644
23645         save_layout_restore_at_exit $MOUNT
23646
23647         # parent set default stripe count only, child will stripe from both
23648         # parent and fs default
23649         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23650                 error "setstripe $MOUNT failed"
23651         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23652         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23653         for i in $(seq 10); do
23654                 local f=$DIR/$tdir/$tfile.$i
23655                 touch $f || error "touch failed"
23656                 local count=$($LFS getstripe -c $f)
23657                 [ $count -eq $OSTCOUNT ] ||
23658                         error "$f stripe count $count != $OSTCOUNT"
23659                 local offset=$($LFS getstripe -i $f)
23660                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23661                 local size=$($LFS getstripe -S $f)
23662                 [ $size -eq $((def_stripe_size * 2)) ] ||
23663                         error "$f stripe size $size != $((def_stripe_size * 2))"
23664                 local pool=$($LFS getstripe -p $f)
23665                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23666         done
23667
23668         # change fs default striping, delete parent default striping, now child
23669         # will stripe from new fs default striping only
23670         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23671                 error "change $MOUNT default stripe failed"
23672         $LFS setstripe -c 0 $DIR/$tdir ||
23673                 error "delete $tdir default stripe failed"
23674         for i in $(seq 11 20); do
23675                 local f=$DIR/$tdir/$tfile.$i
23676                 touch $f || error "touch $f failed"
23677                 local count=$($LFS getstripe -c $f)
23678                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23679                 local offset=$($LFS getstripe -i $f)
23680                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23681                 local size=$($LFS getstripe -S $f)
23682                 [ $size -eq $def_stripe_size ] ||
23683                         error "$f stripe size $size != $def_stripe_size"
23684                 local pool=$($LFS getstripe -p $f)
23685                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23686         done
23687
23688         unlinkmany $DIR/$tdir/$tfile. 1 20
23689
23690         local f=$DIR/$tdir/$tfile
23691         pool_remove_all_targets $test_pool $f
23692         pool_remove $test_pool $f
23693 }
23694 run_test 406 "DNE support fs default striping"
23695
23696 test_407() {
23697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23698         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23699                 skip "Need MDS version at least 2.8.55"
23700         remote_mds_nodsh && skip "remote MDS with nodsh"
23701
23702         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23703                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23704         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23705                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23706         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23707
23708         #define OBD_FAIL_DT_TXN_STOP    0x2019
23709         for idx in $(seq $MDSCOUNT); do
23710                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23711         done
23712         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23713         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23714                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23715         true
23716 }
23717 run_test 407 "transaction fail should cause operation fail"
23718
23719 test_408() {
23720         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23721
23722         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23723         lctl set_param fail_loc=0x8000040a
23724         # let ll_prepare_partial_page() fail
23725         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23726
23727         rm -f $DIR/$tfile
23728
23729         # create at least 100 unused inodes so that
23730         # shrink_icache_memory(0) should not return 0
23731         touch $DIR/$tfile-{0..100}
23732         rm -f $DIR/$tfile-{0..100}
23733         sync
23734
23735         echo 2 > /proc/sys/vm/drop_caches
23736 }
23737 run_test 408 "drop_caches should not hang due to page leaks"
23738
23739 test_409()
23740 {
23741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23742
23743         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23744         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23745         touch $DIR/$tdir/guard || error "(2) Fail to create"
23746
23747         local PREFIX=$(str_repeat 'A' 128)
23748         echo "Create 1K hard links start at $(date)"
23749         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23750                 error "(3) Fail to hard link"
23751
23752         echo "Links count should be right although linkEA overflow"
23753         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23754         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23755         [ $linkcount -eq 1001 ] ||
23756                 error "(5) Unexpected hard links count: $linkcount"
23757
23758         echo "List all links start at $(date)"
23759         ls -l $DIR/$tdir/foo > /dev/null ||
23760                 error "(6) Fail to list $DIR/$tdir/foo"
23761
23762         echo "Unlink hard links start at $(date)"
23763         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23764                 error "(7) Fail to unlink"
23765         echo "Unlink hard links finished at $(date)"
23766 }
23767 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23768
23769 test_410()
23770 {
23771         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23772                 skip "Need client version at least 2.9.59"
23773         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23774                 skip "Need MODULES build"
23775
23776         # Create a file, and stat it from the kernel
23777         local testfile=$DIR/$tfile
23778         touch $testfile
23779
23780         local run_id=$RANDOM
23781         local my_ino=$(stat --format "%i" $testfile)
23782
23783         # Try to insert the module. This will always fail as the
23784         # module is designed to not be inserted.
23785         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23786             &> /dev/null
23787
23788         # Anything but success is a test failure
23789         dmesg | grep -q \
23790             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23791             error "no inode match"
23792 }
23793 run_test 410 "Test inode number returned from kernel thread"
23794
23795 cleanup_test411_cgroup() {
23796         trap 0
23797         rmdir "$1"
23798 }
23799
23800 test_411() {
23801         local cg_basedir=/sys/fs/cgroup/memory
23802         # LU-9966
23803         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23804                 skip "no setup for cgroup"
23805
23806         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23807                 error "test file creation failed"
23808         cancel_lru_locks osc
23809
23810         # Create a very small memory cgroup to force a slab allocation error
23811         local cgdir=$cg_basedir/osc_slab_alloc
23812         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23813         trap "cleanup_test411_cgroup $cgdir" EXIT
23814         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23815         echo 1M > $cgdir/memory.limit_in_bytes
23816
23817         # Should not LBUG, just be killed by oom-killer
23818         # dd will return 0 even allocation failure in some environment.
23819         # So don't check return value
23820         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23821         cleanup_test411_cgroup $cgdir
23822
23823         return 0
23824 }
23825 run_test 411 "Slab allocation error with cgroup does not LBUG"
23826
23827 test_412() {
23828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23829         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23830                 skip "Need server version at least 2.10.55"
23831         fi
23832
23833         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23834                 error "mkdir failed"
23835         $LFS getdirstripe $DIR/$tdir
23836         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23837         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23838                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23839         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23840         [ $stripe_count -eq 2 ] ||
23841                 error "expect 2 get $stripe_count"
23842 }
23843 run_test 412 "mkdir on specific MDTs"
23844
23845 test_qos_mkdir() {
23846         local mkdir_cmd=$1
23847         local stripe_count=$2
23848         local mdts=$(comma_list $(mdts_nodes))
23849
23850         local testdir
23851         local lmv_qos_prio_free
23852         local lmv_qos_threshold_rr
23853         local lmv_qos_maxage
23854         local lod_qos_prio_free
23855         local lod_qos_threshold_rr
23856         local lod_qos_maxage
23857         local count
23858         local i
23859
23860         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23861         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23862         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23863                 head -n1)
23864         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23865         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23866         stack_trap "$LCTL set_param \
23867                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23868         stack_trap "$LCTL set_param \
23869                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23870         stack_trap "$LCTL set_param \
23871                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23872
23873         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23874                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23875         lod_qos_prio_free=${lod_qos_prio_free%%%}
23876         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23877                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23878         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23879         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23880                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23881         stack_trap "do_nodes $mdts $LCTL set_param \
23882                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23883         stack_trap "do_nodes $mdts $LCTL set_param \
23884                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23885                 EXIT
23886         stack_trap "do_nodes $mdts $LCTL set_param \
23887                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23888
23889         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23890         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23891
23892         testdir=$DIR/$tdir-s$stripe_count/rr
23893
23894         local stripe_index=$($LFS getstripe -m $testdir)
23895         local test_mkdir_rr=true
23896
23897         getfattr -d -m dmv $testdir | grep dmv
23898         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
23899                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
23900
23901                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
23902         fi
23903
23904         echo
23905         $test_mkdir_rr &&
23906                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
23907                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
23908
23909         for i in $(seq $((100 * MDSCOUNT))); do
23910                 eval $mkdir_cmd $testdir/subdir$i ||
23911                         error "$mkdir_cmd subdir$i failed"
23912         done
23913
23914         for i in $(seq $MDSCOUNT); do
23915                 count=$($LFS getdirstripe -i $testdir/* |
23916                                 grep ^$((i - 1))$ | wc -l)
23917                 echo "$count directories created on MDT$((i - 1))"
23918                 if $test_mkdir_rr; then
23919                         (( $count == 100 )) ||
23920                                 error "subdirs are not evenly distributed"
23921                 elif [ $((i - 1)) -eq $stripe_index ]; then
23922                         (( $count == 100 * MDSCOUNT )) ||
23923                                 error "$count subdirs created on MDT$((i - 1))"
23924                 else
23925                         (( $count == 0 )) ||
23926                                 error "$count subdirs created on MDT$((i - 1))"
23927                 fi
23928
23929                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
23930                         count=$($LFS getdirstripe $testdir/* |
23931                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23932                         echo "$count stripes created on MDT$((i - 1))"
23933                         # deviation should < 5% of average
23934                         (( $count < 95 * stripe_count )) ||
23935                         (( $count > 105 * stripe_count)) &&
23936                                 error "stripes are not evenly distributed"
23937                 fi
23938         done
23939
23940         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23941         do_nodes $mdts $LCTL set_param \
23942                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23943
23944         echo
23945         echo "Check for uneven MDTs: "
23946
23947         local ffree
23948         local bavail
23949         local max
23950         local min
23951         local max_index
23952         local min_index
23953         local tmp
23954
23955         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23956         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23957         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23958
23959         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23960         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23961         max_index=0
23962         min_index=0
23963         for ((i = 1; i < ${#ffree[@]}; i++)); do
23964                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23965                 if [ $tmp -gt $max ]; then
23966                         max=$tmp
23967                         max_index=$i
23968                 fi
23969                 if [ $tmp -lt $min ]; then
23970                         min=$tmp
23971                         min_index=$i
23972                 fi
23973         done
23974
23975         (( ${ffree[min_index]} == 0 )) &&
23976                 skip "no free files in MDT$min_index"
23977         (( ${ffree[min_index]} > 100000000 )) &&
23978                 skip "too many free files in MDT$min_index"
23979
23980         # Check if we need to generate uneven MDTs
23981         local threshold=50
23982         local diff=$(((max - min) * 100 / min))
23983         local value="$(generate_string 1024)"
23984
23985         while [ $diff -lt $threshold ]; do
23986                 # generate uneven MDTs, create till $threshold% diff
23987                 echo -n "weight diff=$diff% must be > $threshold% ..."
23988                 count=$((${ffree[min_index]} / 10))
23989                 # 50 sec per 10000 files in vm
23990                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
23991                         skip "$count files to create"
23992                 echo "Fill MDT$min_index with $count files"
23993                 [ -d $DIR/$tdir-MDT$min_index ] ||
23994                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23995                         error "mkdir $tdir-MDT$min_index failed"
23996                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
23997                         error "create d$count failed"
23998
23999                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24000                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24001                 max=$(((${ffree[max_index]} >> 8) * \
24002                         (${bavail[max_index]} * bsize >> 16)))
24003                 min=$(((${ffree[min_index]} >> 8) * \
24004                         (${bavail[min_index]} * bsize >> 16)))
24005                 diff=$(((max - min) * 100 / min))
24006         done
24007
24008         echo "MDT filesfree available: ${ffree[@]}"
24009         echo "MDT blocks available: ${bavail[@]}"
24010         echo "weight diff=$diff%"
24011
24012         echo
24013         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24014
24015         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24016         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24017         # decrease statfs age, so that it can be updated in time
24018         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24019         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24020
24021         sleep 1
24022
24023         testdir=$DIR/$tdir-s$stripe_count/qos
24024
24025         for i in $(seq $((100 * MDSCOUNT))); do
24026                 eval $mkdir_cmd $testdir/subdir$i ||
24027                         error "$mkdir_cmd subdir$i failed"
24028         done
24029
24030         for i in $(seq $MDSCOUNT); do
24031                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24032                         wc -l)
24033                 echo "$count directories created on MDT$((i - 1))"
24034
24035                 if [ $stripe_count -gt 1 ]; then
24036                         count=$($LFS getdirstripe $testdir/* |
24037                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24038                         echo "$count stripes created on MDT$((i - 1))"
24039                 fi
24040         done
24041
24042         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24043         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24044
24045         # D-value should > 10% of averge
24046         (( $max - $min < 10 )) &&
24047                 error "subdirs shouldn't be evenly distributed"
24048
24049         # ditto
24050         if [ $stripe_count -gt 1 ]; then
24051                 max=$($LFS getdirstripe $testdir/* |
24052                         grep -P "^\s+$max_index\t" | wc -l)
24053                 min=$($LFS getdirstripe $testdir/* |
24054                         grep -P "^\s+$min_index\t" | wc -l)
24055                 (( $max - $min < 10 * $stripe_count )) &&
24056                         error "stripes shouldn't be evenly distributed"|| true
24057         fi
24058 }
24059
24060 test_413a() {
24061         [ $MDSCOUNT -lt 2 ] &&
24062                 skip "We need at least 2 MDTs for this test"
24063
24064         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24065                 skip "Need server version at least 2.12.52"
24066
24067         local stripe_count
24068
24069         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24070                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24071                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24072                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24073                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24074         done
24075 }
24076 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24077
24078 test_413b() {
24079         [ $MDSCOUNT -lt 2 ] &&
24080                 skip "We need at least 2 MDTs for this test"
24081
24082         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24083                 skip "Need server version at least 2.12.52"
24084
24085         local testdir
24086         local stripe_count
24087
24088         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24089                 testdir=$DIR/$tdir-s$stripe_count
24090                 mkdir $testdir || error "mkdir $testdir failed"
24091                 mkdir $testdir/rr || error "mkdir rr failed"
24092                 mkdir $testdir/qos || error "mkdir qos failed"
24093                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24094                         $testdir/rr || error "setdirstripe rr failed"
24095                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24096                         error "setdirstripe failed"
24097                 test_qos_mkdir "mkdir" $stripe_count
24098         done
24099 }
24100 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24101
24102 test_413c() {
24103         [ $MDSCOUNT -ge 2 ] ||
24104                 skip "We need at least 2 MDTs for this test"
24105
24106         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24107                 skip "Need server version at least 2.14.50"
24108
24109         local testdir
24110         local inherit
24111         local inherit_rr
24112
24113         testdir=$DIR/${tdir}-s1
24114         mkdir $testdir || error "mkdir $testdir failed"
24115         mkdir $testdir/rr || error "mkdir rr failed"
24116         mkdir $testdir/qos || error "mkdir qos failed"
24117         # default max_inherit is -1, default max_inherit_rr is 0
24118         $LFS setdirstripe -D -c 1 $testdir/rr ||
24119                 error "setdirstripe rr failed"
24120         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24121                 error "setdirstripe qos failed"
24122         test_qos_mkdir "mkdir" 1
24123
24124         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24125         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24126         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24127         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24128         (( $inherit_rr == 0 )) ||
24129                 error "rr/level1 inherit-rr $inherit_rr != 0"
24130
24131         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24132         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24133         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24134         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24135         (( $inherit_rr == 0 )) ||
24136                 error "qos/level1 inherit-rr $inherit_rr !=0"
24137         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24138         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24139                 error "level2 shouldn't have default LMV" || true
24140 }
24141 run_test 413c "mkdir with default LMV max inherit rr"
24142
24143 test_414() {
24144 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24145         $LCTL set_param fail_loc=0x80000521
24146         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24147         rm -f $DIR/$tfile
24148 }
24149 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24150
24151 test_415() {
24152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24153         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24154                 skip "Need server version at least 2.11.52"
24155
24156         # LU-11102
24157         local total
24158         local setattr_pid
24159         local start_time
24160         local end_time
24161         local duration
24162
24163         total=500
24164         # this test may be slow on ZFS
24165         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24166
24167         # though this test is designed for striped directory, let's test normal
24168         # directory too since lock is always saved as CoS lock.
24169         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24170         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24171
24172         (
24173                 while true; do
24174                         touch $DIR/$tdir
24175                 done
24176         ) &
24177         setattr_pid=$!
24178
24179         start_time=$(date +%s)
24180         for i in $(seq $total); do
24181                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24182                         > /dev/null
24183         done
24184         end_time=$(date +%s)
24185         duration=$((end_time - start_time))
24186
24187         kill -9 $setattr_pid
24188
24189         echo "rename $total files took $duration sec"
24190         [ $duration -lt 100 ] || error "rename took $duration sec"
24191 }
24192 run_test 415 "lock revoke is not missing"
24193
24194 test_416() {
24195         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24196                 skip "Need server version at least 2.11.55"
24197
24198         # define OBD_FAIL_OSD_TXN_START    0x19a
24199         do_facet mds1 lctl set_param fail_loc=0x19a
24200
24201         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24202
24203         true
24204 }
24205 run_test 416 "transaction start failure won't cause system hung"
24206
24207 cleanup_417() {
24208         trap 0
24209         do_nodes $(comma_list $(mdts_nodes)) \
24210                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24211         do_nodes $(comma_list $(mdts_nodes)) \
24212                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24213         do_nodes $(comma_list $(mdts_nodes)) \
24214                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24215 }
24216
24217 test_417() {
24218         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24219         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24220                 skip "Need MDS version at least 2.11.56"
24221
24222         trap cleanup_417 RETURN EXIT
24223
24224         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24225         do_nodes $(comma_list $(mdts_nodes)) \
24226                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24227         $LFS migrate -m 0 $DIR/$tdir.1 &&
24228                 error "migrate dir $tdir.1 should fail"
24229
24230         do_nodes $(comma_list $(mdts_nodes)) \
24231                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24232         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24233                 error "create remote dir $tdir.2 should fail"
24234
24235         do_nodes $(comma_list $(mdts_nodes)) \
24236                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24237         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24238                 error "create striped dir $tdir.3 should fail"
24239         true
24240 }
24241 run_test 417 "disable remote dir, striped dir and dir migration"
24242
24243 # Checks that the outputs of df [-i] and lfs df [-i] match
24244 #
24245 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24246 check_lfs_df() {
24247         local dir=$2
24248         local inodes
24249         local df_out
24250         local lfs_df_out
24251         local count
24252         local passed=false
24253
24254         # blocks or inodes
24255         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24256
24257         for count in {1..100}; do
24258                 cancel_lru_locks
24259                 sync; sleep 0.2
24260
24261                 # read the lines of interest
24262                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24263                         error "df $inodes $dir | tail -n +2 failed"
24264                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24265                         error "lfs df $inodes $dir | grep summary: failed"
24266
24267                 # skip first substrings of each output as they are different
24268                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24269                 # compare the two outputs
24270                 passed=true
24271                 for i in {1..5}; do
24272                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24273                 done
24274                 $passed && break
24275         done
24276
24277         if ! $passed; then
24278                 df -P $inodes $dir
24279                 echo
24280                 lfs df $inodes $dir
24281                 error "df and lfs df $1 output mismatch: "      \
24282                       "df ${inodes}: ${df_out[*]}, "            \
24283                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24284         fi
24285 }
24286
24287 test_418() {
24288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24289
24290         local dir=$DIR/$tdir
24291         local numfiles=$((RANDOM % 4096 + 2))
24292         local numblocks=$((RANDOM % 256 + 1))
24293
24294         wait_delete_completed
24295         test_mkdir $dir
24296
24297         # check block output
24298         check_lfs_df blocks $dir
24299         # check inode output
24300         check_lfs_df inodes $dir
24301
24302         # create a single file and retest
24303         echo "Creating a single file and testing"
24304         createmany -o $dir/$tfile- 1 &>/dev/null ||
24305                 error "creating 1 file in $dir failed"
24306         check_lfs_df blocks $dir
24307         check_lfs_df inodes $dir
24308
24309         # create a random number of files
24310         echo "Creating $((numfiles - 1)) files and testing"
24311         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24312                 error "creating $((numfiles - 1)) files in $dir failed"
24313
24314         # write a random number of blocks to the first test file
24315         echo "Writing $numblocks 4K blocks and testing"
24316         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24317                 count=$numblocks &>/dev/null ||
24318                 error "dd to $dir/${tfile}-0 failed"
24319
24320         # retest
24321         check_lfs_df blocks $dir
24322         check_lfs_df inodes $dir
24323
24324         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24325                 error "unlinking $numfiles files in $dir failed"
24326 }
24327 run_test 418 "df and lfs df outputs match"
24328
24329 test_419()
24330 {
24331         local dir=$DIR/$tdir
24332
24333         mkdir -p $dir
24334         touch $dir/file
24335
24336         cancel_lru_locks mdc
24337
24338         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24339         $LCTL set_param fail_loc=0x1410
24340         cat $dir/file
24341         $LCTL set_param fail_loc=0
24342         rm -rf $dir
24343 }
24344 run_test 419 "Verify open file by name doesn't crash kernel"
24345
24346 test_420()
24347 {
24348         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24349                 skip "Need MDS version at least 2.12.53"
24350
24351         local SAVE_UMASK=$(umask)
24352         local dir=$DIR/$tdir
24353         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24354
24355         mkdir -p $dir
24356         umask 0000
24357         mkdir -m03777 $dir/testdir
24358         ls -dn $dir/testdir
24359         # Need to remove trailing '.' when SELinux is enabled
24360         local dirperms=$(ls -dn $dir/testdir |
24361                          awk '{ sub(/\.$/, "", $1); print $1}')
24362         [ $dirperms == "drwxrwsrwt" ] ||
24363                 error "incorrect perms on $dir/testdir"
24364
24365         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24366                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24367         ls -n $dir/testdir/testfile
24368         local fileperms=$(ls -n $dir/testdir/testfile |
24369                           awk '{ sub(/\.$/, "", $1); print $1}')
24370         [ $fileperms == "-rwxr-xr-x" ] ||
24371                 error "incorrect perms on $dir/testdir/testfile"
24372
24373         umask $SAVE_UMASK
24374 }
24375 run_test 420 "clear SGID bit on non-directories for non-members"
24376
24377 test_421a() {
24378         local cnt
24379         local fid1
24380         local fid2
24381
24382         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24383                 skip "Need MDS version at least 2.12.54"
24384
24385         test_mkdir $DIR/$tdir
24386         createmany -o $DIR/$tdir/f 3
24387         cnt=$(ls -1 $DIR/$tdir | wc -l)
24388         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24389
24390         fid1=$(lfs path2fid $DIR/$tdir/f1)
24391         fid2=$(lfs path2fid $DIR/$tdir/f2)
24392         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24393
24394         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24395         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24396
24397         cnt=$(ls -1 $DIR/$tdir | wc -l)
24398         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24399
24400         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24401         createmany -o $DIR/$tdir/f 3
24402         cnt=$(ls -1 $DIR/$tdir | wc -l)
24403         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24404
24405         fid1=$(lfs path2fid $DIR/$tdir/f1)
24406         fid2=$(lfs path2fid $DIR/$tdir/f2)
24407         echo "remove using fsname $FSNAME"
24408         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24409
24410         cnt=$(ls -1 $DIR/$tdir | wc -l)
24411         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24412 }
24413 run_test 421a "simple rm by fid"
24414
24415 test_421b() {
24416         local cnt
24417         local FID1
24418         local FID2
24419
24420         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24421                 skip "Need MDS version at least 2.12.54"
24422
24423         test_mkdir $DIR/$tdir
24424         createmany -o $DIR/$tdir/f 3
24425         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24426         MULTIPID=$!
24427
24428         FID1=$(lfs path2fid $DIR/$tdir/f1)
24429         FID2=$(lfs path2fid $DIR/$tdir/f2)
24430         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24431
24432         kill -USR1 $MULTIPID
24433         wait
24434
24435         cnt=$(ls $DIR/$tdir | wc -l)
24436         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24437 }
24438 run_test 421b "rm by fid on open file"
24439
24440 test_421c() {
24441         local cnt
24442         local FIDS
24443
24444         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24445                 skip "Need MDS version at least 2.12.54"
24446
24447         test_mkdir $DIR/$tdir
24448         createmany -o $DIR/$tdir/f 3
24449         touch $DIR/$tdir/$tfile
24450         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24451         cnt=$(ls -1 $DIR/$tdir | wc -l)
24452         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24453
24454         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24455         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24456
24457         cnt=$(ls $DIR/$tdir | wc -l)
24458         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24459 }
24460 run_test 421c "rm by fid against hardlinked files"
24461
24462 test_421d() {
24463         local cnt
24464         local FIDS
24465
24466         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24467                 skip "Need MDS version at least 2.12.54"
24468
24469         test_mkdir $DIR/$tdir
24470         createmany -o $DIR/$tdir/f 4097
24471         cnt=$(ls -1 $DIR/$tdir | wc -l)
24472         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24473
24474         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24475         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24476
24477         cnt=$(ls $DIR/$tdir | wc -l)
24478         rm -rf $DIR/$tdir
24479         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24480 }
24481 run_test 421d "rmfid en masse"
24482
24483 test_421e() {
24484         local cnt
24485         local FID
24486
24487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24488         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24489                 skip "Need MDS version at least 2.12.54"
24490
24491         mkdir -p $DIR/$tdir
24492         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24493         createmany -o $DIR/$tdir/striped_dir/f 512
24494         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24495         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24496
24497         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24498                 sed "s/[/][^:]*://g")
24499         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24500
24501         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24502         rm -rf $DIR/$tdir
24503         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24504 }
24505 run_test 421e "rmfid in DNE"
24506
24507 test_421f() {
24508         local cnt
24509         local FID
24510
24511         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24512                 skip "Need MDS version at least 2.12.54"
24513
24514         test_mkdir $DIR/$tdir
24515         touch $DIR/$tdir/f
24516         cnt=$(ls -1 $DIR/$tdir | wc -l)
24517         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24518
24519         FID=$(lfs path2fid $DIR/$tdir/f)
24520         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24521         # rmfid should fail
24522         cnt=$(ls -1 $DIR/$tdir | wc -l)
24523         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24524
24525         chmod a+rw $DIR/$tdir
24526         ls -la $DIR/$tdir
24527         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24528         # rmfid should fail
24529         cnt=$(ls -1 $DIR/$tdir | wc -l)
24530         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24531
24532         rm -f $DIR/$tdir/f
24533         $RUNAS touch $DIR/$tdir/f
24534         FID=$(lfs path2fid $DIR/$tdir/f)
24535         echo "rmfid as root"
24536         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24537         cnt=$(ls -1 $DIR/$tdir | wc -l)
24538         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24539
24540         rm -f $DIR/$tdir/f
24541         $RUNAS touch $DIR/$tdir/f
24542         cnt=$(ls -1 $DIR/$tdir | wc -l)
24543         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24544         FID=$(lfs path2fid $DIR/$tdir/f)
24545         # rmfid w/o user_fid2path mount option should fail
24546         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24547         cnt=$(ls -1 $DIR/$tdir | wc -l)
24548         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24549
24550         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24551         stack_trap "rmdir $tmpdir"
24552         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24553                 error "failed to mount client'"
24554         stack_trap "umount_client $tmpdir"
24555
24556         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24557         # rmfid should succeed
24558         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24559         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24560
24561         # rmfid shouldn't allow to remove files due to dir's permission
24562         chmod a+rwx $tmpdir/$tdir
24563         touch $tmpdir/$tdir/f
24564         ls -la $tmpdir/$tdir
24565         FID=$(lfs path2fid $tmpdir/$tdir/f)
24566         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24567         return 0
24568 }
24569 run_test 421f "rmfid checks permissions"
24570
24571 test_421g() {
24572         local cnt
24573         local FIDS
24574
24575         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24576         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24577                 skip "Need MDS version at least 2.12.54"
24578
24579         mkdir -p $DIR/$tdir
24580         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24581         createmany -o $DIR/$tdir/striped_dir/f 512
24582         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24583         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24584
24585         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24586                 sed "s/[/][^:]*://g")
24587
24588         rm -f $DIR/$tdir/striped_dir/f1*
24589         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24590         removed=$((512 - cnt))
24591
24592         # few files have been just removed, so we expect
24593         # rmfid to fail on their fids
24594         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24595         [ $removed != $errors ] && error "$errors != $removed"
24596
24597         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24598         rm -rf $DIR/$tdir
24599         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24600 }
24601 run_test 421g "rmfid to return errors properly"
24602
24603 test_422() {
24604         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24605         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24606         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24607         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24608         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24609
24610         local amc=$(at_max_get client)
24611         local amo=$(at_max_get mds1)
24612         local timeout=`lctl get_param -n timeout`
24613
24614         at_max_set 0 client
24615         at_max_set 0 mds1
24616
24617 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24618         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24619                         fail_val=$(((2*timeout + 10)*1000))
24620         touch $DIR/$tdir/d3/file &
24621         sleep 2
24622 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24623         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24624                         fail_val=$((2*timeout + 5))
24625         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24626         local pid=$!
24627         sleep 1
24628         kill -9 $pid
24629         sleep $((2 * timeout))
24630         echo kill $pid
24631         kill -9 $pid
24632         lctl mark touch
24633         touch $DIR/$tdir/d2/file3
24634         touch $DIR/$tdir/d2/file4
24635         touch $DIR/$tdir/d2/file5
24636
24637         wait
24638         at_max_set $amc client
24639         at_max_set $amo mds1
24640
24641         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24642         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24643                 error "Watchdog is always throttled"
24644 }
24645 run_test 422 "kill a process with RPC in progress"
24646
24647 stat_test() {
24648     df -h $MOUNT &
24649     df -h $MOUNT &
24650     df -h $MOUNT &
24651     df -h $MOUNT &
24652     df -h $MOUNT &
24653     df -h $MOUNT &
24654 }
24655
24656 test_423() {
24657     local _stats
24658     # ensure statfs cache is expired
24659     sleep 2;
24660
24661     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24662     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24663
24664     return 0
24665 }
24666 run_test 423 "statfs should return a right data"
24667
24668 test_424() {
24669 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24670         $LCTL set_param fail_loc=0x80000522
24671         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24672         rm -f $DIR/$tfile
24673 }
24674 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24675
24676 test_425() {
24677         test_mkdir -c -1 $DIR/$tdir
24678         $LFS setstripe -c -1 $DIR/$tdir
24679
24680         lru_resize_disable "" 100
24681         stack_trap "lru_resize_enable" EXIT
24682
24683         sleep 5
24684
24685         for i in $(seq $((MDSCOUNT * 125))); do
24686                 local t=$DIR/$tdir/$tfile_$i
24687
24688                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24689                         error_noexit "Create file $t"
24690         done
24691         stack_trap "rm -rf $DIR/$tdir" EXIT
24692
24693         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24694                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24695                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24696
24697                 [ $lock_count -le $lru_size ] ||
24698                         error "osc lock count $lock_count > lru size $lru_size"
24699         done
24700
24701         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24702                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24703                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24704
24705                 [ $lock_count -le $lru_size ] ||
24706                         error "mdc lock count $lock_count > lru size $lru_size"
24707         done
24708 }
24709 run_test 425 "lock count should not exceed lru size"
24710
24711 test_426() {
24712         splice-test -r $DIR/$tfile
24713         splice-test -rd $DIR/$tfile
24714         splice-test $DIR/$tfile
24715         splice-test -d $DIR/$tfile
24716 }
24717 run_test 426 "splice test on Lustre"
24718
24719 test_427() {
24720         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24721         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24722                 skip "Need MDS version at least 2.12.4"
24723         local log
24724
24725         mkdir $DIR/$tdir
24726         mkdir $DIR/$tdir/1
24727         mkdir $DIR/$tdir/2
24728         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24729         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24730
24731         $LFS getdirstripe $DIR/$tdir/1/dir
24732
24733         #first setfattr for creating updatelog
24734         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24735
24736 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24737         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24738         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24739         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24740
24741         sleep 2
24742         fail mds2
24743         wait_recovery_complete mds2 $((2*TIMEOUT))
24744
24745         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24746         echo $log | grep "get update log failed" &&
24747                 error "update log corruption is detected" || true
24748 }
24749 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24750
24751 test_428() {
24752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24753         local cache_limit=$CACHE_MAX
24754
24755         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24756         $LCTL set_param -n llite.*.max_cached_mb=64
24757
24758         mkdir $DIR/$tdir
24759         $LFS setstripe -c 1 $DIR/$tdir
24760         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24761         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24762         #test write
24763         for f in $(seq 4); do
24764                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24765         done
24766         wait
24767
24768         cancel_lru_locks osc
24769         # Test read
24770         for f in $(seq 4); do
24771                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24772         done
24773         wait
24774 }
24775 run_test 428 "large block size IO should not hang"
24776
24777 test_429() { # LU-7915 / LU-10948
24778         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24779         local testfile=$DIR/$tfile
24780         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24781         local new_flag=1
24782         local first_rpc
24783         local second_rpc
24784         local third_rpc
24785
24786         $LCTL get_param $ll_opencache_threshold_count ||
24787                 skip "client does not have opencache parameter"
24788
24789         set_opencache $new_flag
24790         stack_trap "restore_opencache"
24791         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24792                 error "enable opencache failed"
24793         touch $testfile
24794         # drop MDC DLM locks
24795         cancel_lru_locks mdc
24796         # clear MDC RPC stats counters
24797         $LCTL set_param $mdc_rpcstats=clear
24798
24799         # According to the current implementation, we need to run 3 times
24800         # open & close file to verify if opencache is enabled correctly.
24801         # 1st, RPCs are sent for lookup/open and open handle is released on
24802         #      close finally.
24803         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24804         #      so open handle won't be released thereafter.
24805         # 3rd, No RPC is sent out.
24806         $MULTIOP $testfile oc || error "multiop failed"
24807         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24808         echo "1st: $first_rpc RPCs in flight"
24809
24810         $MULTIOP $testfile oc || error "multiop failed"
24811         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24812         echo "2nd: $second_rpc RPCs in flight"
24813
24814         $MULTIOP $testfile oc || error "multiop failed"
24815         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24816         echo "3rd: $third_rpc RPCs in flight"
24817
24818         #verify no MDC RPC is sent
24819         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
24820 }
24821 run_test 429 "verify if opencache flag on client side does work"
24822
24823 lseek_test_430() {
24824         local offset
24825         local file=$1
24826
24827         # data at [200K, 400K)
24828         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24829                 error "256K->512K dd fails"
24830         # data at [2M, 3M)
24831         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24832                 error "2M->3M dd fails"
24833         # data at [4M, 5M)
24834         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24835                 error "4M->5M dd fails"
24836         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24837         # start at first component hole #1
24838         printf "Seeking hole from 1000 ... "
24839         offset=$(lseek_test -l 1000 $file)
24840         echo $offset
24841         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24842         printf "Seeking data from 1000 ... "
24843         offset=$(lseek_test -d 1000 $file)
24844         echo $offset
24845         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24846
24847         # start at first component data block
24848         printf "Seeking hole from 300000 ... "
24849         offset=$(lseek_test -l 300000 $file)
24850         echo $offset
24851         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24852         printf "Seeking data from 300000 ... "
24853         offset=$(lseek_test -d 300000 $file)
24854         echo $offset
24855         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24856
24857         # start at the first component but beyond end of object size
24858         printf "Seeking hole from 1000000 ... "
24859         offset=$(lseek_test -l 1000000 $file)
24860         echo $offset
24861         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24862         printf "Seeking data from 1000000 ... "
24863         offset=$(lseek_test -d 1000000 $file)
24864         echo $offset
24865         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24866
24867         # start at second component stripe 2 (empty file)
24868         printf "Seeking hole from 1500000 ... "
24869         offset=$(lseek_test -l 1500000 $file)
24870         echo $offset
24871         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24872         printf "Seeking data from 1500000 ... "
24873         offset=$(lseek_test -d 1500000 $file)
24874         echo $offset
24875         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24876
24877         # start at second component stripe 1 (all data)
24878         printf "Seeking hole from 3000000 ... "
24879         offset=$(lseek_test -l 3000000 $file)
24880         echo $offset
24881         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24882         printf "Seeking data from 3000000 ... "
24883         offset=$(lseek_test -d 3000000 $file)
24884         echo $offset
24885         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24886
24887         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24888                 error "2nd dd fails"
24889         echo "Add data block at 640K...1280K"
24890
24891         # start at before new data block, in hole
24892         printf "Seeking hole from 600000 ... "
24893         offset=$(lseek_test -l 600000 $file)
24894         echo $offset
24895         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24896         printf "Seeking data from 600000 ... "
24897         offset=$(lseek_test -d 600000 $file)
24898         echo $offset
24899         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24900
24901         # start at the first component new data block
24902         printf "Seeking hole from 1000000 ... "
24903         offset=$(lseek_test -l 1000000 $file)
24904         echo $offset
24905         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24906         printf "Seeking data from 1000000 ... "
24907         offset=$(lseek_test -d 1000000 $file)
24908         echo $offset
24909         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24910
24911         # start at second component stripe 2, new data
24912         printf "Seeking hole from 1200000 ... "
24913         offset=$(lseek_test -l 1200000 $file)
24914         echo $offset
24915         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24916         printf "Seeking data from 1200000 ... "
24917         offset=$(lseek_test -d 1200000 $file)
24918         echo $offset
24919         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24920
24921         # start beyond file end
24922         printf "Using offset > filesize ... "
24923         lseek_test -l 4000000 $file && error "lseek should fail"
24924         printf "Using offset > filesize ... "
24925         lseek_test -d 4000000 $file && error "lseek should fail"
24926
24927         printf "Done\n\n"
24928 }
24929
24930 test_430a() {
24931         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24932                 skip "MDT does not support SEEK_HOLE"
24933
24934         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24935                 skip "OST does not support SEEK_HOLE"
24936
24937         local file=$DIR/$tdir/$tfile
24938
24939         mkdir -p $DIR/$tdir
24940
24941         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24942         # OST stripe #1 will have continuous data at [1M, 3M)
24943         # OST stripe #2 is empty
24944         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24945         lseek_test_430 $file
24946         rm $file
24947         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24948         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24949         lseek_test_430 $file
24950         rm $file
24951         $LFS setstripe -c2 -S 512K $file
24952         echo "Two stripes, stripe size 512K"
24953         lseek_test_430 $file
24954         rm $file
24955         # FLR with stale mirror
24956         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24957                        -N -c2 -S 1M $file
24958         echo "Mirrored file:"
24959         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24960         echo "Plain 2 stripes 1M"
24961         lseek_test_430 $file
24962         rm $file
24963 }
24964 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24965
24966 test_430b() {
24967         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24968                 skip "OST does not support SEEK_HOLE"
24969
24970         local offset
24971         local file=$DIR/$tdir/$tfile
24972
24973         mkdir -p $DIR/$tdir
24974         # Empty layout lseek should fail
24975         $MCREATE $file
24976         # seek from 0
24977         printf "Seeking hole from 0 ... "
24978         lseek_test -l 0 $file && error "lseek should fail"
24979         printf "Seeking data from 0 ... "
24980         lseek_test -d 0 $file && error "lseek should fail"
24981         rm $file
24982
24983         # 1M-hole file
24984         $LFS setstripe -E 1M -c2 -E eof $file
24985         $TRUNCATE $file 1048576
24986         printf "Seeking hole from 1000000 ... "
24987         offset=$(lseek_test -l 1000000 $file)
24988         echo $offset
24989         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24990         printf "Seeking data from 1000000 ... "
24991         lseek_test -d 1000000 $file && error "lseek should fail"
24992         rm $file
24993
24994         # full component followed by non-inited one
24995         $LFS setstripe -E 1M -c2 -E eof $file
24996         dd if=/dev/urandom of=$file bs=1M count=1
24997         printf "Seeking hole from 1000000 ... "
24998         offset=$(lseek_test -l 1000000 $file)
24999         echo $offset
25000         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25001         printf "Seeking hole from 1048576 ... "
25002         lseek_test -l 1048576 $file && error "lseek should fail"
25003         # init second component and truncate back
25004         echo "123" >> $file
25005         $TRUNCATE $file 1048576
25006         printf "Seeking hole from 1000000 ... "
25007         offset=$(lseek_test -l 1000000 $file)
25008         echo $offset
25009         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25010         printf "Seeking hole from 1048576 ... "
25011         lseek_test -l 1048576 $file && error "lseek should fail"
25012         # boundary checks for big values
25013         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25014         offset=$(lseek_test -d 0 $file.10g)
25015         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25016         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25017         offset=$(lseek_test -d 0 $file.100g)
25018         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25019         return 0
25020 }
25021 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25022
25023 test_430c() {
25024         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25025                 skip "OST does not support SEEK_HOLE"
25026
25027         local file=$DIR/$tdir/$tfile
25028         local start
25029
25030         mkdir -p $DIR/$tdir
25031         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25032
25033         # cp version 8.33+ prefers lseek over fiemap
25034         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25035                 start=$SECONDS
25036                 time cp $file /dev/null
25037                 (( SECONDS - start < 5 )) ||
25038                         error "cp: too long runtime $((SECONDS - start))"
25039
25040         fi
25041         # tar version 1.29+ supports SEEK_HOLE/DATA
25042         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25043                 start=$SECONDS
25044                 time tar cS $file - | cat > /dev/null
25045                 (( SECONDS - start < 5 )) ||
25046                         error "tar: too long runtime $((SECONDS - start))"
25047         fi
25048 }
25049 run_test 430c "lseek: external tools check"
25050
25051 test_431() { # LU-14187
25052         local file=$DIR/$tdir/$tfile
25053
25054         mkdir -p $DIR/$tdir
25055         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25056         dd if=/dev/urandom of=$file bs=4k count=1
25057         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25058         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25059         #define OBD_FAIL_OST_RESTART_IO 0x251
25060         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25061         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25062         cp $file $file.0
25063         cancel_lru_locks
25064         sync_all_data
25065         echo 3 > /proc/sys/vm/drop_caches
25066         diff  $file $file.0 || error "data diff"
25067 }
25068 run_test 431 "Restart transaction for IO"
25069
25070 prep_801() {
25071         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25072         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25073                 skip "Need server version at least 2.9.55"
25074
25075         start_full_debug_logging
25076 }
25077
25078 post_801() {
25079         stop_full_debug_logging
25080 }
25081
25082 barrier_stat() {
25083         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25084                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25085                            awk '/The barrier for/ { print $7 }')
25086                 echo $st
25087         else
25088                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25089                 echo \'$st\'
25090         fi
25091 }
25092
25093 barrier_expired() {
25094         local expired
25095
25096         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25097                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25098                           awk '/will be expired/ { print $7 }')
25099         else
25100                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25101         fi
25102
25103         echo $expired
25104 }
25105
25106 test_801a() {
25107         prep_801
25108
25109         echo "Start barrier_freeze at: $(date)"
25110         #define OBD_FAIL_BARRIER_DELAY          0x2202
25111         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25112         # Do not reduce barrier time - See LU-11873
25113         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25114
25115         sleep 2
25116         local b_status=$(barrier_stat)
25117         echo "Got barrier status at: $(date)"
25118         [ "$b_status" = "'freezing_p1'" ] ||
25119                 error "(1) unexpected barrier status $b_status"
25120
25121         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25122         wait
25123         b_status=$(barrier_stat)
25124         [ "$b_status" = "'frozen'" ] ||
25125                 error "(2) unexpected barrier status $b_status"
25126
25127         local expired=$(barrier_expired)
25128         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25129         sleep $((expired + 3))
25130
25131         b_status=$(barrier_stat)
25132         [ "$b_status" = "'expired'" ] ||
25133                 error "(3) unexpected barrier status $b_status"
25134
25135         # Do not reduce barrier time - See LU-11873
25136         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25137                 error "(4) fail to freeze barrier"
25138
25139         b_status=$(barrier_stat)
25140         [ "$b_status" = "'frozen'" ] ||
25141                 error "(5) unexpected barrier status $b_status"
25142
25143         echo "Start barrier_thaw at: $(date)"
25144         #define OBD_FAIL_BARRIER_DELAY          0x2202
25145         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25146         do_facet mgs $LCTL barrier_thaw $FSNAME &
25147
25148         sleep 2
25149         b_status=$(barrier_stat)
25150         echo "Got barrier status at: $(date)"
25151         [ "$b_status" = "'thawing'" ] ||
25152                 error "(6) unexpected barrier status $b_status"
25153
25154         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25155         wait
25156         b_status=$(barrier_stat)
25157         [ "$b_status" = "'thawed'" ] ||
25158                 error "(7) unexpected barrier status $b_status"
25159
25160         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25161         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25162         do_facet mgs $LCTL barrier_freeze $FSNAME
25163
25164         b_status=$(barrier_stat)
25165         [ "$b_status" = "'failed'" ] ||
25166                 error "(8) unexpected barrier status $b_status"
25167
25168         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25169         do_facet mgs $LCTL barrier_thaw $FSNAME
25170
25171         post_801
25172 }
25173 run_test 801a "write barrier user interfaces and stat machine"
25174
25175 test_801b() {
25176         prep_801
25177
25178         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25179         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25180         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25181         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25182         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25183
25184         cancel_lru_locks mdc
25185
25186         # 180 seconds should be long enough
25187         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25188
25189         local b_status=$(barrier_stat)
25190         [ "$b_status" = "'frozen'" ] ||
25191                 error "(6) unexpected barrier status $b_status"
25192
25193         mkdir $DIR/$tdir/d0/d10 &
25194         mkdir_pid=$!
25195
25196         touch $DIR/$tdir/d1/f13 &
25197         touch_pid=$!
25198
25199         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25200         ln_pid=$!
25201
25202         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25203         mv_pid=$!
25204
25205         rm -f $DIR/$tdir/d4/f12 &
25206         rm_pid=$!
25207
25208         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25209
25210         # To guarantee taht the 'stat' is not blocked
25211         b_status=$(barrier_stat)
25212         [ "$b_status" = "'frozen'" ] ||
25213                 error "(8) unexpected barrier status $b_status"
25214
25215         # let above commands to run at background
25216         sleep 5
25217
25218         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25219         ps -p $touch_pid || error "(10) touch should be blocked"
25220         ps -p $ln_pid || error "(11) link should be blocked"
25221         ps -p $mv_pid || error "(12) rename should be blocked"
25222         ps -p $rm_pid || error "(13) unlink should be blocked"
25223
25224         b_status=$(barrier_stat)
25225         [ "$b_status" = "'frozen'" ] ||
25226                 error "(14) unexpected barrier status $b_status"
25227
25228         do_facet mgs $LCTL barrier_thaw $FSNAME
25229         b_status=$(barrier_stat)
25230         [ "$b_status" = "'thawed'" ] ||
25231                 error "(15) unexpected barrier status $b_status"
25232
25233         wait $mkdir_pid || error "(16) mkdir should succeed"
25234         wait $touch_pid || error "(17) touch should succeed"
25235         wait $ln_pid || error "(18) link should succeed"
25236         wait $mv_pid || error "(19) rename should succeed"
25237         wait $rm_pid || error "(20) unlink should succeed"
25238
25239         post_801
25240 }
25241 run_test 801b "modification will be blocked by write barrier"
25242
25243 test_801c() {
25244         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25245
25246         prep_801
25247
25248         stop mds2 || error "(1) Fail to stop mds2"
25249
25250         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25251
25252         local b_status=$(barrier_stat)
25253         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25254                 do_facet mgs $LCTL barrier_thaw $FSNAME
25255                 error "(2) unexpected barrier status $b_status"
25256         }
25257
25258         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25259                 error "(3) Fail to rescan barrier bitmap"
25260
25261         # Do not reduce barrier time - See LU-11873
25262         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25263
25264         b_status=$(barrier_stat)
25265         [ "$b_status" = "'frozen'" ] ||
25266                 error "(4) unexpected barrier status $b_status"
25267
25268         do_facet mgs $LCTL barrier_thaw $FSNAME
25269         b_status=$(barrier_stat)
25270         [ "$b_status" = "'thawed'" ] ||
25271                 error "(5) unexpected barrier status $b_status"
25272
25273         local devname=$(mdsdevname 2)
25274
25275         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25276
25277         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25278                 error "(7) Fail to rescan barrier bitmap"
25279
25280         post_801
25281 }
25282 run_test 801c "rescan barrier bitmap"
25283
25284 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25285 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25286 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25287 saved_MOUNT_OPTS=$MOUNT_OPTS
25288
25289 cleanup_802a() {
25290         trap 0
25291
25292         stopall
25293         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25294         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25295         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25296         MOUNT_OPTS=$saved_MOUNT_OPTS
25297         setupall
25298 }
25299
25300 test_802a() {
25301         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25302         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25303         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25304                 skip "Need server version at least 2.9.55"
25305
25306         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25307
25308         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25309
25310         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25311                 error "(2) Fail to copy"
25312
25313         trap cleanup_802a EXIT
25314
25315         # sync by force before remount as readonly
25316         sync; sync_all_data; sleep 3; sync_all_data
25317
25318         stopall
25319
25320         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25321         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25322         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25323
25324         echo "Mount the server as read only"
25325         setupall server_only || error "(3) Fail to start servers"
25326
25327         echo "Mount client without ro should fail"
25328         mount_client $MOUNT &&
25329                 error "(4) Mount client without 'ro' should fail"
25330
25331         echo "Mount client with ro should succeed"
25332         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25333         mount_client $MOUNT ||
25334                 error "(5) Mount client with 'ro' should succeed"
25335
25336         echo "Modify should be refused"
25337         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25338
25339         echo "Read should be allowed"
25340         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25341                 error "(7) Read should succeed under ro mode"
25342
25343         cleanup_802a
25344 }
25345 run_test 802a "simulate readonly device"
25346
25347 test_802b() {
25348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25349         remote_mds_nodsh && skip "remote MDS with nodsh"
25350
25351         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25352                 skip "readonly option not available"
25353
25354         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25355
25356         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25357                 error "(2) Fail to copy"
25358
25359         # write back all cached data before setting MDT to readonly
25360         cancel_lru_locks
25361         sync_all_data
25362
25363         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25364         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25365
25366         echo "Modify should be refused"
25367         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25368
25369         echo "Read should be allowed"
25370         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25371                 error "(7) Read should succeed under ro mode"
25372
25373         # disable readonly
25374         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25375 }
25376 run_test 802b "be able to set MDTs to readonly"
25377
25378 test_803a() {
25379         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25380         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25381                 skip "MDS needs to be newer than 2.10.54"
25382
25383         mkdir -p $DIR/$tdir
25384         # Create some objects on all MDTs to trigger related logs objects
25385         for idx in $(seq $MDSCOUNT); do
25386                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25387                         $DIR/$tdir/dir${idx} ||
25388                         error "Fail to create $DIR/$tdir/dir${idx}"
25389         done
25390
25391         sync; sleep 3
25392         wait_delete_completed # ensure old test cleanups are finished
25393         echo "before create:"
25394         $LFS df -i $MOUNT
25395         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25396
25397         for i in {1..10}; do
25398                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25399                         error "Fail to create $DIR/$tdir/foo$i"
25400         done
25401
25402         sync; sleep 3
25403         echo "after create:"
25404         $LFS df -i $MOUNT
25405         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25406
25407         # allow for an llog to be cleaned up during the test
25408         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25409                 error "before ($before_used) + 10 > after ($after_used)"
25410
25411         for i in {1..10}; do
25412                 rm -rf $DIR/$tdir/foo$i ||
25413                         error "Fail to remove $DIR/$tdir/foo$i"
25414         done
25415
25416         sleep 3 # avoid MDT return cached statfs
25417         wait_delete_completed
25418         echo "after unlink:"
25419         $LFS df -i $MOUNT
25420         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25421
25422         # allow for an llog to be created during the test
25423         [ $after_used -le $((before_used + 1)) ] ||
25424                 error "after ($after_used) > before ($before_used) + 1"
25425 }
25426 run_test 803a "verify agent object for remote object"
25427
25428 test_803b() {
25429         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25430         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25431                 skip "MDS needs to be newer than 2.13.56"
25432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25433
25434         for i in $(seq 0 $((MDSCOUNT - 1))); do
25435                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25436         done
25437
25438         local before=0
25439         local after=0
25440
25441         local tmp
25442
25443         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25444         for i in $(seq 0 $((MDSCOUNT - 1))); do
25445                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25446                         awk '/getattr/ { print $2 }')
25447                 before=$((before + tmp))
25448         done
25449         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25450         for i in $(seq 0 $((MDSCOUNT - 1))); do
25451                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25452                         awk '/getattr/ { print $2 }')
25453                 after=$((after + tmp))
25454         done
25455
25456         [ $before -eq $after ] || error "getattr count $before != $after"
25457 }
25458 run_test 803b "remote object can getattr from cache"
25459
25460 test_804() {
25461         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25462         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25463                 skip "MDS needs to be newer than 2.10.54"
25464         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25465
25466         mkdir -p $DIR/$tdir
25467         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25468                 error "Fail to create $DIR/$tdir/dir0"
25469
25470         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25471         local dev=$(mdsdevname 2)
25472
25473         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25474                 grep ${fid} || error "NOT found agent entry for dir0"
25475
25476         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25477                 error "Fail to create $DIR/$tdir/dir1"
25478
25479         touch $DIR/$tdir/dir1/foo0 ||
25480                 error "Fail to create $DIR/$tdir/dir1/foo0"
25481         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25482         local rc=0
25483
25484         for idx in $(seq $MDSCOUNT); do
25485                 dev=$(mdsdevname $idx)
25486                 do_facet mds${idx} \
25487                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25488                         grep ${fid} && rc=$idx
25489         done
25490
25491         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25492                 error "Fail to rename foo0 to foo1"
25493         if [ $rc -eq 0 ]; then
25494                 for idx in $(seq $MDSCOUNT); do
25495                         dev=$(mdsdevname $idx)
25496                         do_facet mds${idx} \
25497                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25498                         grep ${fid} && rc=$idx
25499                 done
25500         fi
25501
25502         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25503                 error "Fail to rename foo1 to foo2"
25504         if [ $rc -eq 0 ]; then
25505                 for idx in $(seq $MDSCOUNT); do
25506                         dev=$(mdsdevname $idx)
25507                         do_facet mds${idx} \
25508                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25509                         grep ${fid} && rc=$idx
25510                 done
25511         fi
25512
25513         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25514
25515         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25516                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25517         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25518                 error "Fail to rename foo2 to foo0"
25519         unlink $DIR/$tdir/dir1/foo0 ||
25520                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25521         rm -rf $DIR/$tdir/dir0 ||
25522                 error "Fail to rm $DIR/$tdir/dir0"
25523
25524         for idx in $(seq $MDSCOUNT); do
25525                 dev=$(mdsdevname $idx)
25526                 rc=0
25527
25528                 stop mds${idx}
25529                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25530                         rc=$?
25531                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25532                         error "mount mds$idx failed"
25533                 df $MOUNT > /dev/null 2>&1
25534
25535                 # e2fsck should not return error
25536                 [ $rc -eq 0 ] ||
25537                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25538         done
25539 }
25540 run_test 804 "verify agent entry for remote entry"
25541
25542 cleanup_805() {
25543         do_facet $SINGLEMDS zfs set quota=$old $fsset
25544         unlinkmany $DIR/$tdir/f- 1000000
25545         trap 0
25546 }
25547
25548 test_805() {
25549         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25550         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25551         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25552                 skip "netfree not implemented before 0.7"
25553         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25554                 skip "Need MDS version at least 2.10.57"
25555
25556         local fsset
25557         local freekb
25558         local usedkb
25559         local old
25560         local quota
25561         local pref="osd-zfs.$FSNAME-MDT0000."
25562
25563         # limit available space on MDS dataset to meet nospace issue
25564         # quickly. then ZFS 0.7.2 can use reserved space if asked
25565         # properly (using netfree flag in osd_declare_destroy()
25566         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25567         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25568                 gawk '{print $3}')
25569         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25570         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25571         let "usedkb=usedkb-freekb"
25572         let "freekb=freekb/2"
25573         if let "freekb > 5000"; then
25574                 let "freekb=5000"
25575         fi
25576         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25577         trap cleanup_805 EXIT
25578         mkdir $DIR/$tdir
25579         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25580                 error "Can't set PFL layout"
25581         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25582         rm -rf $DIR/$tdir || error "not able to remove"
25583         do_facet $SINGLEMDS zfs set quota=$old $fsset
25584         trap 0
25585 }
25586 run_test 805 "ZFS can remove from full fs"
25587
25588 # Size-on-MDS test
25589 check_lsom_data()
25590 {
25591         local file=$1
25592         local expect=$(stat -c %s $file)
25593
25594         check_lsom_size $1 $expect
25595
25596         local blocks=$($LFS getsom -b $file)
25597         expect=$(stat -c %b $file)
25598         [[ $blocks == $expect ]] ||
25599                 error "$file expected blocks: $expect, got: $blocks"
25600 }
25601
25602 check_lsom_size()
25603 {
25604         local size
25605         local expect=$2
25606
25607         cancel_lru_locks mdc
25608
25609         size=$($LFS getsom -s $1)
25610         [[ $size == $expect ]] ||
25611                 error "$file expected size: $expect, got: $size"
25612 }
25613
25614 test_806() {
25615         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25616                 skip "Need MDS version at least 2.11.52"
25617
25618         local bs=1048576
25619
25620         touch $DIR/$tfile || error "touch $tfile failed"
25621
25622         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25623         save_lustre_params client "llite.*.xattr_cache" > $save
25624         lctl set_param llite.*.xattr_cache=0
25625         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25626
25627         # single-threaded write
25628         echo "Test SOM for single-threaded write"
25629         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25630                 error "write $tfile failed"
25631         check_lsom_size $DIR/$tfile $bs
25632
25633         local num=32
25634         local size=$(($num * $bs))
25635         local offset=0
25636         local i
25637
25638         echo "Test SOM for single client multi-threaded($num) write"
25639         $TRUNCATE $DIR/$tfile 0
25640         for ((i = 0; i < $num; i++)); do
25641                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25642                 local pids[$i]=$!
25643                 offset=$((offset + $bs))
25644         done
25645         for (( i=0; i < $num; i++ )); do
25646                 wait ${pids[$i]}
25647         done
25648         check_lsom_size $DIR/$tfile $size
25649
25650         $TRUNCATE $DIR/$tfile 0
25651         for ((i = 0; i < $num; i++)); do
25652                 offset=$((offset - $bs))
25653                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25654                 local pids[$i]=$!
25655         done
25656         for (( i=0; i < $num; i++ )); do
25657                 wait ${pids[$i]}
25658         done
25659         check_lsom_size $DIR/$tfile $size
25660
25661         # multi-client writes
25662         num=$(get_node_count ${CLIENTS//,/ })
25663         size=$(($num * $bs))
25664         offset=0
25665         i=0
25666
25667         echo "Test SOM for multi-client ($num) writes"
25668         $TRUNCATE $DIR/$tfile 0
25669         for client in ${CLIENTS//,/ }; do
25670                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25671                 local pids[$i]=$!
25672                 i=$((i + 1))
25673                 offset=$((offset + $bs))
25674         done
25675         for (( i=0; i < $num; i++ )); do
25676                 wait ${pids[$i]}
25677         done
25678         check_lsom_size $DIR/$tfile $offset
25679
25680         i=0
25681         $TRUNCATE $DIR/$tfile 0
25682         for client in ${CLIENTS//,/ }; do
25683                 offset=$((offset - $bs))
25684                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25685                 local pids[$i]=$!
25686                 i=$((i + 1))
25687         done
25688         for (( i=0; i < $num; i++ )); do
25689                 wait ${pids[$i]}
25690         done
25691         check_lsom_size $DIR/$tfile $size
25692
25693         # verify truncate
25694         echo "Test SOM for truncate"
25695         $TRUNCATE $DIR/$tfile 1048576
25696         check_lsom_size $DIR/$tfile 1048576
25697         $TRUNCATE $DIR/$tfile 1234
25698         check_lsom_size $DIR/$tfile 1234
25699
25700         # verify SOM blocks count
25701         echo "Verify SOM block count"
25702         $TRUNCATE $DIR/$tfile 0
25703         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25704                 error "failed to write file $tfile"
25705         check_lsom_data $DIR/$tfile
25706 }
25707 run_test 806 "Verify Lazy Size on MDS"
25708
25709 test_807() {
25710         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25711         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25712                 skip "Need MDS version at least 2.11.52"
25713
25714         # Registration step
25715         changelog_register || error "changelog_register failed"
25716         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25717         changelog_users $SINGLEMDS | grep -q $cl_user ||
25718                 error "User $cl_user not found in changelog_users"
25719
25720         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25721         save_lustre_params client "llite.*.xattr_cache" > $save
25722         lctl set_param llite.*.xattr_cache=0
25723         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25724
25725         rm -rf $DIR/$tdir || error "rm $tdir failed"
25726         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25727         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25728         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25729         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25730                 error "truncate $tdir/trunc failed"
25731
25732         local bs=1048576
25733         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25734                 error "write $tfile failed"
25735
25736         # multi-client wirtes
25737         local num=$(get_node_count ${CLIENTS//,/ })
25738         local offset=0
25739         local i=0
25740
25741         echo "Test SOM for multi-client ($num) writes"
25742         touch $DIR/$tfile || error "touch $tfile failed"
25743         $TRUNCATE $DIR/$tfile 0
25744         for client in ${CLIENTS//,/ }; do
25745                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25746                 local pids[$i]=$!
25747                 i=$((i + 1))
25748                 offset=$((offset + $bs))
25749         done
25750         for (( i=0; i < $num; i++ )); do
25751                 wait ${pids[$i]}
25752         done
25753
25754         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25755         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25756         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25757         check_lsom_data $DIR/$tdir/trunc
25758         check_lsom_data $DIR/$tdir/single_dd
25759         check_lsom_data $DIR/$tfile
25760
25761         rm -rf $DIR/$tdir
25762         # Deregistration step
25763         changelog_deregister || error "changelog_deregister failed"
25764 }
25765 run_test 807 "verify LSOM syncing tool"
25766
25767 check_som_nologged()
25768 {
25769         local lines=$($LFS changelog $FSNAME-MDT0000 |
25770                 grep 'x=trusted.som' | wc -l)
25771         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25772 }
25773
25774 test_808() {
25775         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25776                 skip "Need MDS version at least 2.11.55"
25777
25778         # Registration step
25779         changelog_register || error "changelog_register failed"
25780
25781         touch $DIR/$tfile || error "touch $tfile failed"
25782         check_som_nologged
25783
25784         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25785                 error "write $tfile failed"
25786         check_som_nologged
25787
25788         $TRUNCATE $DIR/$tfile 1234
25789         check_som_nologged
25790
25791         $TRUNCATE $DIR/$tfile 1048576
25792         check_som_nologged
25793
25794         # Deregistration step
25795         changelog_deregister || error "changelog_deregister failed"
25796 }
25797 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25798
25799 check_som_nodata()
25800 {
25801         $LFS getsom $1
25802         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25803 }
25804
25805 test_809() {
25806         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25807                 skip "Need MDS version at least 2.11.56"
25808
25809         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25810                 error "failed to create DoM-only file $DIR/$tfile"
25811         touch $DIR/$tfile || error "touch $tfile failed"
25812         check_som_nodata $DIR/$tfile
25813
25814         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25815                 error "write $tfile failed"
25816         check_som_nodata $DIR/$tfile
25817
25818         $TRUNCATE $DIR/$tfile 1234
25819         check_som_nodata $DIR/$tfile
25820
25821         $TRUNCATE $DIR/$tfile 4097
25822         check_som_nodata $DIR/$file
25823 }
25824 run_test 809 "Verify no SOM xattr store for DoM-only files"
25825
25826 test_810() {
25827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25828         $GSS && skip_env "could not run with gss"
25829         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25830                 skip "OST < 2.12.58 doesn't align checksum"
25831
25832         set_checksums 1
25833         stack_trap "set_checksums $ORIG_CSUM" EXIT
25834         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25835
25836         local csum
25837         local before
25838         local after
25839         for csum in $CKSUM_TYPES; do
25840                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25841                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25842                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25843                         eval set -- $i
25844                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25845                         before=$(md5sum $DIR/$tfile)
25846                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25847                         after=$(md5sum $DIR/$tfile)
25848                         [ "$before" == "$after" ] ||
25849                                 error "$csum: $before != $after bs=$1 seek=$2"
25850                 done
25851         done
25852 }
25853 run_test 810 "partial page writes on ZFS (LU-11663)"
25854
25855 test_812a() {
25856         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25857                 skip "OST < 2.12.51 doesn't support this fail_loc"
25858
25859         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25860         # ensure ost1 is connected
25861         stat $DIR/$tfile >/dev/null || error "can't stat"
25862         wait_osc_import_state client ost1 FULL
25863         # no locks, no reqs to let the connection idle
25864         cancel_lru_locks osc
25865
25866         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25867 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25868         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25869         wait_osc_import_state client ost1 CONNECTING
25870         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25871
25872         stat $DIR/$tfile >/dev/null || error "can't stat file"
25873 }
25874 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25875
25876 test_812b() { # LU-12378
25877         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25878                 skip "OST < 2.12.51 doesn't support this fail_loc"
25879
25880         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25881         # ensure ost1 is connected
25882         stat $DIR/$tfile >/dev/null || error "can't stat"
25883         wait_osc_import_state client ost1 FULL
25884         # no locks, no reqs to let the connection idle
25885         cancel_lru_locks osc
25886
25887         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25888 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25889         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25890         wait_osc_import_state client ost1 CONNECTING
25891         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25892
25893         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25894         wait_osc_import_state client ost1 IDLE
25895 }
25896 run_test 812b "do not drop no resend request for idle connect"
25897
25898 test_812c() {
25899         local old
25900
25901         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25902
25903         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25904         $LFS getstripe $DIR/$tfile
25905         $LCTL set_param osc.*.idle_timeout=10
25906         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25907         # ensure ost1 is connected
25908         stat $DIR/$tfile >/dev/null || error "can't stat"
25909         wait_osc_import_state client ost1 FULL
25910         # no locks, no reqs to let the connection idle
25911         cancel_lru_locks osc
25912
25913 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25914         $LCTL set_param fail_loc=0x80000533
25915         sleep 15
25916         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25917 }
25918 run_test 812c "idle import vs lock enqueue race"
25919
25920 test_813() {
25921         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25922         [ -z "$file_heat_sav" ] && skip "no file heat support"
25923
25924         local readsample
25925         local writesample
25926         local readbyte
25927         local writebyte
25928         local readsample1
25929         local writesample1
25930         local readbyte1
25931         local writebyte1
25932
25933         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25934         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25935
25936         $LCTL set_param -n llite.*.file_heat=1
25937         echo "Turn on file heat"
25938         echo "Period second: $period_second, Decay percentage: $decay_pct"
25939
25940         echo "QQQQ" > $DIR/$tfile
25941         echo "QQQQ" > $DIR/$tfile
25942         echo "QQQQ" > $DIR/$tfile
25943         cat $DIR/$tfile > /dev/null
25944         cat $DIR/$tfile > /dev/null
25945         cat $DIR/$tfile > /dev/null
25946         cat $DIR/$tfile > /dev/null
25947
25948         local out=$($LFS heat_get $DIR/$tfile)
25949
25950         $LFS heat_get $DIR/$tfile
25951         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25952         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25953         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25954         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25955
25956         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25957         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25958         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25959         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25960
25961         sleep $((period_second + 3))
25962         echo "Sleep $((period_second + 3)) seconds..."
25963         # The recursion formula to calculate the heat of the file f is as
25964         # follow:
25965         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25966         # Where Hi is the heat value in the period between time points i*I and
25967         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25968         # to the weight of Ci.
25969         out=$($LFS heat_get $DIR/$tfile)
25970         $LFS heat_get $DIR/$tfile
25971         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25972         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25973         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25974         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25975
25976         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25977                 error "read sample ($readsample) is wrong"
25978         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25979                 error "write sample ($writesample) is wrong"
25980         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25981                 error "read bytes ($readbyte) is wrong"
25982         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25983                 error "write bytes ($writebyte) is wrong"
25984
25985         echo "QQQQ" > $DIR/$tfile
25986         echo "QQQQ" > $DIR/$tfile
25987         echo "QQQQ" > $DIR/$tfile
25988         cat $DIR/$tfile > /dev/null
25989         cat $DIR/$tfile > /dev/null
25990         cat $DIR/$tfile > /dev/null
25991         cat $DIR/$tfile > /dev/null
25992
25993         sleep $((period_second + 3))
25994         echo "Sleep $((period_second + 3)) seconds..."
25995
25996         out=$($LFS heat_get $DIR/$tfile)
25997         $LFS heat_get $DIR/$tfile
25998         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25999         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26000         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26001         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26002
26003         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26004                 4 * $decay_pct) / 100") -eq 1 ] ||
26005                 error "read sample ($readsample1) is wrong"
26006         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26007                 3 * $decay_pct) / 100") -eq 1 ] ||
26008                 error "write sample ($writesample1) is wrong"
26009         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26010                 20 * $decay_pct) / 100") -eq 1 ] ||
26011                 error "read bytes ($readbyte1) is wrong"
26012         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26013                 15 * $decay_pct) / 100") -eq 1 ] ||
26014                 error "write bytes ($writebyte1) is wrong"
26015
26016         echo "Turn off file heat for the file $DIR/$tfile"
26017         $LFS heat_set -o $DIR/$tfile
26018
26019         echo "QQQQ" > $DIR/$tfile
26020         echo "QQQQ" > $DIR/$tfile
26021         echo "QQQQ" > $DIR/$tfile
26022         cat $DIR/$tfile > /dev/null
26023         cat $DIR/$tfile > /dev/null
26024         cat $DIR/$tfile > /dev/null
26025         cat $DIR/$tfile > /dev/null
26026
26027         out=$($LFS heat_get $DIR/$tfile)
26028         $LFS heat_get $DIR/$tfile
26029         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26030         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26031         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26032         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26033
26034         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26035         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26036         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26037         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26038
26039         echo "Trun on file heat for the file $DIR/$tfile"
26040         $LFS heat_set -O $DIR/$tfile
26041
26042         echo "QQQQ" > $DIR/$tfile
26043         echo "QQQQ" > $DIR/$tfile
26044         echo "QQQQ" > $DIR/$tfile
26045         cat $DIR/$tfile > /dev/null
26046         cat $DIR/$tfile > /dev/null
26047         cat $DIR/$tfile > /dev/null
26048         cat $DIR/$tfile > /dev/null
26049
26050         out=$($LFS heat_get $DIR/$tfile)
26051         $LFS heat_get $DIR/$tfile
26052         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26053         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26054         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26055         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26056
26057         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26058         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26059         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26060         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26061
26062         $LFS heat_set -c $DIR/$tfile
26063         $LCTL set_param -n llite.*.file_heat=0
26064         echo "Turn off file heat support for the Lustre filesystem"
26065
26066         echo "QQQQ" > $DIR/$tfile
26067         echo "QQQQ" > $DIR/$tfile
26068         echo "QQQQ" > $DIR/$tfile
26069         cat $DIR/$tfile > /dev/null
26070         cat $DIR/$tfile > /dev/null
26071         cat $DIR/$tfile > /dev/null
26072         cat $DIR/$tfile > /dev/null
26073
26074         out=$($LFS heat_get $DIR/$tfile)
26075         $LFS heat_get $DIR/$tfile
26076         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26077         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26078         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26079         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26080
26081         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26082         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26083         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26084         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26085
26086         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26087         rm -f $DIR/$tfile
26088 }
26089 run_test 813 "File heat verfication"
26090
26091 test_814()
26092 {
26093         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26094         echo -n y >> $DIR/$tfile
26095         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26096         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26097 }
26098 run_test 814 "sparse cp works as expected (LU-12361)"
26099
26100 test_815()
26101 {
26102         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26103         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26104 }
26105 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26106
26107 test_816() {
26108         local ost1_imp=$(get_osc_import_name client ost1)
26109         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26110                          cut -d'.' -f2)
26111
26112         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26113         # ensure ost1 is connected
26114
26115         stat $DIR/$tfile >/dev/null || error "can't stat"
26116         wait_osc_import_state client ost1 FULL
26117         # no locks, no reqs to let the connection idle
26118         cancel_lru_locks osc
26119         lru_resize_disable osc
26120         local before
26121         local now
26122         before=$($LCTL get_param -n \
26123                  ldlm.namespaces.$imp_name.lru_size)
26124
26125         wait_osc_import_state client ost1 IDLE
26126         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26127         now=$($LCTL get_param -n \
26128               ldlm.namespaces.$imp_name.lru_size)
26129         [ $before == $now ] || error "lru_size changed $before != $now"
26130 }
26131 run_test 816 "do not reset lru_resize on idle reconnect"
26132
26133 cleanup_817() {
26134         umount $tmpdir
26135         exportfs -u localhost:$DIR/nfsexp
26136         rm -rf $DIR/nfsexp
26137 }
26138
26139 test_817() {
26140         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26141
26142         mkdir -p $DIR/nfsexp
26143         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26144                 error "failed to export nfs"
26145
26146         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26147         stack_trap cleanup_817 EXIT
26148
26149         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26150                 error "failed to mount nfs to $tmpdir"
26151
26152         cp /bin/true $tmpdir
26153         $DIR/nfsexp/true || error "failed to execute 'true' command"
26154 }
26155 run_test 817 "nfsd won't cache write lock for exec file"
26156
26157 test_818() {
26158         mkdir $DIR/$tdir
26159         $LFS setstripe -c1 -i0 $DIR/$tfile
26160         $LFS setstripe -c1 -i1 $DIR/$tfile
26161         stop $SINGLEMDS
26162         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26163         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26164         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26165                 error "start $SINGLEMDS failed"
26166         rm -rf $DIR/$tdir
26167 }
26168 run_test 818 "unlink with failed llog"
26169
26170 test_819a() {
26171         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26172         cancel_lru_locks osc
26173         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26174         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26175         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26176         rm -f $TDIR/$tfile
26177 }
26178 run_test 819a "too big niobuf in read"
26179
26180 test_819b() {
26181         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26182         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26183         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26184         cancel_lru_locks osc
26185         sleep 1
26186         rm -f $TDIR/$tfile
26187 }
26188 run_test 819b "too big niobuf in write"
26189
26190
26191 function test_820_start_ost() {
26192         sleep 5
26193
26194         for num in $(seq $OSTCOUNT); do
26195                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26196         done
26197 }
26198
26199 test_820() {
26200         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26201
26202         mkdir $DIR/$tdir
26203         umount_client $MOUNT || error "umount failed"
26204         for num in $(seq $OSTCOUNT); do
26205                 stop ost$num
26206         done
26207
26208         # mount client with no active OSTs
26209         # so that the client can't initialize max LOV EA size
26210         # from OSC notifications
26211         mount_client $MOUNT || error "mount failed"
26212         # delay OST starting to keep this 0 max EA size for a while
26213         test_820_start_ost &
26214
26215         # create a directory on MDS2
26216         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26217                 error "Failed to create directory"
26218         # open intent should update default EA size
26219         # see mdc_update_max_ea_from_body()
26220         # notice this is the very first RPC to MDS2
26221         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26222         ret=$?
26223         echo $out
26224         # With SSK, this situation can lead to -EPERM being returned.
26225         # In that case, simply retry.
26226         if [ $ret -ne 0 ] && $SHARED_KEY; then
26227                 if echo "$out" | grep -q "not permitted"; then
26228                         cp /etc/services $DIR/$tdir/mds2
26229                         ret=$?
26230                 fi
26231         fi
26232         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26233 }
26234 run_test 820 "update max EA from open intent"
26235
26236 test_822() {
26237         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26238
26239         save_lustre_params mds1 \
26240                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26241         do_facet $SINGLEMDS "$LCTL set_param -n \
26242                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26243         do_facet $SINGLEMDS "$LCTL set_param -n \
26244                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26245
26246         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26247         local maxage=$(do_facet mds1 $LCTL get_param -n \
26248                        osp.$FSNAME-OST0000*MDT0000.maxage)
26249         sleep $((maxage + 1))
26250
26251         #define OBD_FAIL_NET_ERROR_RPC          0x532
26252         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26253
26254         stack_trap "restore_lustre_params < $p; rm $p"
26255
26256         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26257                       osp.$FSNAME-OST0000*MDT0000.create_count")
26258         for i in $(seq 1 $count); do
26259                 touch $DIR/$tfile.${i} || error "touch failed"
26260         done
26261 }
26262 run_test 822 "test precreate failure"
26263
26264 #
26265 # tests that do cleanup/setup should be run at the end
26266 #
26267
26268 test_900() {
26269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26270         local ls
26271
26272         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26273         $LCTL set_param fail_loc=0x903
26274
26275         cancel_lru_locks MGC
26276
26277         FAIL_ON_ERROR=true cleanup
26278         FAIL_ON_ERROR=true setup
26279 }
26280 run_test 900 "umount should not race with any mgc requeue thread"
26281
26282 # LUS-6253/LU-11185
26283 test_901() {
26284         local oldc
26285         local newc
26286         local olds
26287         local news
26288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26289
26290         # some get_param have a bug to handle dot in param name
26291         cancel_lru_locks MGC
26292         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26293         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26294         umount_client $MOUNT || error "umount failed"
26295         mount_client $MOUNT || error "mount failed"
26296         cancel_lru_locks MGC
26297         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26298         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26299
26300         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26301         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26302
26303         return 0
26304 }
26305 run_test 901 "don't leak a mgc lock on client umount"
26306
26307 # LU-13377
26308 test_902() {
26309         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26310                 skip "client does not have LU-13377 fix"
26311         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26312         $LCTL set_param fail_loc=0x1415
26313         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26314         cancel_lru_locks osc
26315         rm -f $DIR/$tfile
26316 }
26317 run_test 902 "test short write doesn't hang lustre"
26318
26319 complete $SECONDS
26320 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26321 check_and_cleanup_lustre
26322 if [ "$I_MOUNTED" != "yes" ]; then
26323         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26324 fi
26325 exit_status