Whamcloud - gitweb
LU-11188 lfs: add "--perm" option to "lfs find"
[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 numdirs=2
5897         local dir=$DIR/$tdir
5898
5899         rm -rf $dir
5900         test_mkdir -p $dir/dir
5901         for i in $(seq $numfiles); do
5902                 touch $dir/file$i
5903                 touch $dir/dir/file$i
5904         done
5905
5906         local numcomp=$($LFS getstripe --component-count $dir)
5907
5908         [[ $numcomp == 0 ]] && numcomp=1
5909
5910         # test lfs getstripe with --recursive
5911         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5912
5913         [[ $filenum -eq $((numfiles * 2)) ]] ||
5914                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5915         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5916         [[ $filenum -eq $numfiles ]] ||
5917                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5918         echo "$LFS getstripe showed obdidx or l_ost_idx"
5919
5920         # test lfs getstripe with file instead of dir
5921         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5922         [[ $filenum -eq 1 ]] ||
5923                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5924         echo "$LFS getstripe file1 passed"
5925
5926         #test lfs getstripe with --verbose
5927         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5928         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5929                 error "$LFS getstripe --verbose $dir: "\
5930                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5931         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5932                 error "$LFS getstripe $dir: showed lmm_magic"
5933
5934         #test lfs getstripe with -v prints lmm_fid
5935         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5936         local countfids=$((numdirs + numfiles * numcomp))
5937         [[ $filenum -eq $countfids ]] ||
5938                 error "$LFS getstripe -v $dir: "\
5939                       "got $filenum want $countfids lmm_fid"
5940         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5941                 error "$LFS getstripe $dir: showed lmm_fid by default"
5942         echo "$LFS getstripe --verbose passed"
5943
5944         #check for FID information
5945         local fid1=$($LFS getstripe --fid $dir/file1)
5946         local fid2=$($LFS getstripe --verbose $dir/file1 |
5947                      awk '/lmm_fid: / { print $2; exit; }')
5948         local fid3=$($LFS path2fid $dir/file1)
5949
5950         [ "$fid1" != "$fid2" ] &&
5951                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5952         [ "$fid1" != "$fid3" ] &&
5953                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5954         echo "$LFS getstripe --fid passed"
5955
5956         #test lfs getstripe with --obd
5957         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5958                 error "$LFS getstripe --obd wrong_uuid: should return error"
5959
5960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5961
5962         local ostidx=1
5963         local obduuid=$(ostuuid_from_index $ostidx)
5964         local found=$($LFS getstripe -r --obd $obduuid $dir |
5965                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5966
5967         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5968         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5969                 ((filenum--))
5970         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972
5973         [[ $found -eq $filenum ]] ||
5974                 error "$LFS getstripe --obd: found $found expect $filenum"
5975         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5976                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5977                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5978                 error "$LFS getstripe --obd: should not show file on other obd"
5979         echo "$LFS getstripe --obd passed"
5980 }
5981 run_test 56a "check $LFS getstripe"
5982
5983 test_56b() {
5984         local dir=$DIR/$tdir
5985         local numdirs=3
5986
5987         test_mkdir $dir
5988         for i in $(seq $numdirs); do
5989                 test_mkdir $dir/dir$i
5990         done
5991
5992         # test lfs getdirstripe default mode is non-recursion, which is
5993         # different from lfs getstripe
5994         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5995
5996         [[ $dircnt -eq 1 ]] ||
5997                 error "$LFS getdirstripe: found $dircnt, not 1"
5998         dircnt=$($LFS getdirstripe --recursive $dir |
5999                 grep -c lmv_stripe_count)
6000         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6001                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6002 }
6003 run_test 56b "check $LFS getdirstripe"
6004
6005 test_56c() {
6006         remote_ost_nodsh && skip "remote OST with nodsh"
6007
6008         local ost_idx=0
6009         local ost_name=$(ostname_from_index $ost_idx)
6010         local old_status=$(ost_dev_status $ost_idx)
6011         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6012
6013         [[ -z "$old_status" ]] ||
6014                 skip_env "OST $ost_name is in $old_status status"
6015
6016         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6017         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6018                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6019         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6020                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6021                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6022         fi
6023
6024         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6025                 error "$LFS df -v showing inactive devices"
6026         sleep_maxage
6027
6028         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6029
6030         [[ "$new_status" =~ "D" ]] ||
6031                 error "$ost_name status is '$new_status', missing 'D'"
6032         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6033                 [[ "$new_status" =~ "N" ]] ||
6034                         error "$ost_name status is '$new_status', missing 'N'"
6035         fi
6036         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6037                 [[ "$new_status" =~ "f" ]] ||
6038                         error "$ost_name status is '$new_status', missing 'f'"
6039         fi
6040
6041         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6042         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6043                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6044         [[ -z "$p" ]] && restore_lustre_params < $p || true
6045         sleep_maxage
6046
6047         new_status=$(ost_dev_status $ost_idx)
6048         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6049                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6050         # can't check 'f' as devices may actually be on flash
6051 }
6052 run_test 56c "check 'lfs df' showing device status"
6053
6054 test_56d() {
6055         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6056         local osts=$($LFS df -v $MOUNT | grep -c OST)
6057
6058         $LFS df $MOUNT
6059
6060         (( mdts == MDSCOUNT )) ||
6061                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6062         (( osts == OSTCOUNT )) ||
6063                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6064 }
6065 run_test 56d "'lfs df -v' prints only configured devices"
6066
6067 NUMFILES=3
6068 NUMDIRS=3
6069 setup_56() {
6070         local local_tdir="$1"
6071         local local_numfiles="$2"
6072         local local_numdirs="$3"
6073         local dir_params="$4"
6074         local dir_stripe_params="$5"
6075
6076         if [ ! -d "$local_tdir" ] ; then
6077                 test_mkdir -p $dir_stripe_params $local_tdir
6078                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6079                 for i in $(seq $local_numfiles) ; do
6080                         touch $local_tdir/file$i
6081                 done
6082                 for i in $(seq $local_numdirs) ; do
6083                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6084                         for j in $(seq $local_numfiles) ; do
6085                                 touch $local_tdir/dir$i/file$j
6086                         done
6087                 done
6088         fi
6089 }
6090
6091 setup_56_special() {
6092         local local_tdir=$1
6093         local local_numfiles=$2
6094         local local_numdirs=$3
6095
6096         setup_56 $local_tdir $local_numfiles $local_numdirs
6097
6098         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6099                 for i in $(seq $local_numfiles) ; do
6100                         mknod $local_tdir/loop${i}b b 7 $i
6101                         mknod $local_tdir/null${i}c c 1 3
6102                         ln -s $local_tdir/file1 $local_tdir/link${i}
6103                 done
6104                 for i in $(seq $local_numdirs) ; do
6105                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6106                         mknod $local_tdir/dir$i/null${i}c c 1 3
6107                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6108                 done
6109         fi
6110 }
6111
6112 test_56g() {
6113         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6114         local expected=$(($NUMDIRS + 2))
6115
6116         setup_56 $dir $NUMFILES $NUMDIRS
6117
6118         # test lfs find with -name
6119         for i in $(seq $NUMFILES) ; do
6120                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6121
6122                 [ $nums -eq $expected ] ||
6123                         error "lfs find -name '*$i' $dir wrong: "\
6124                               "found $nums, expected $expected"
6125         done
6126 }
6127 run_test 56g "check lfs find -name"
6128
6129 test_56h() {
6130         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6131         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6132
6133         setup_56 $dir $NUMFILES $NUMDIRS
6134
6135         # test lfs find with ! -name
6136         for i in $(seq $NUMFILES) ; do
6137                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6138
6139                 [ $nums -eq $expected ] ||
6140                         error "lfs find ! -name '*$i' $dir wrong: "\
6141                               "found $nums, expected $expected"
6142         done
6143 }
6144 run_test 56h "check lfs find ! -name"
6145
6146 test_56i() {
6147         local dir=$DIR/$tdir
6148
6149         test_mkdir $dir
6150
6151         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6152         local out=$($cmd)
6153
6154         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6155 }
6156 run_test 56i "check 'lfs find -ost UUID' skips directories"
6157
6158 test_56j() {
6159         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6160
6161         setup_56_special $dir $NUMFILES $NUMDIRS
6162
6163         local expected=$((NUMDIRS + 1))
6164         local cmd="$LFS find -type d $dir"
6165         local nums=$($cmd | wc -l)
6166
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169 }
6170 run_test 56j "check lfs find -type d"
6171
6172 test_56k() {
6173         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6174
6175         setup_56_special $dir $NUMFILES $NUMDIRS
6176
6177         local expected=$(((NUMDIRS + 1) * NUMFILES))
6178         local cmd="$LFS find -type f $dir"
6179         local nums=$($cmd | wc -l)
6180
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183 }
6184 run_test 56k "check lfs find -type f"
6185
6186 test_56l() {
6187         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6188
6189         setup_56_special $dir $NUMFILES $NUMDIRS
6190
6191         local expected=$((NUMDIRS + NUMFILES))
6192         local cmd="$LFS find -type b $dir"
6193         local nums=$($cmd | wc -l)
6194
6195         [ $nums -eq $expected ] ||
6196                 error "'$cmd' wrong: found $nums, expected $expected"
6197 }
6198 run_test 56l "check lfs find -type b"
6199
6200 test_56m() {
6201         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6202
6203         setup_56_special $dir $NUMFILES $NUMDIRS
6204
6205         local expected=$((NUMDIRS + NUMFILES))
6206         local cmd="$LFS find -type c $dir"
6207         local nums=$($cmd | wc -l)
6208         [ $nums -eq $expected ] ||
6209                 error "'$cmd' wrong: found $nums, expected $expected"
6210 }
6211 run_test 56m "check lfs find -type c"
6212
6213 test_56n() {
6214         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6215         setup_56_special $dir $NUMFILES $NUMDIRS
6216
6217         local expected=$((NUMDIRS + NUMFILES))
6218         local cmd="$LFS find -type l $dir"
6219         local nums=$($cmd | wc -l)
6220
6221         [ $nums -eq $expected ] ||
6222                 error "'$cmd' wrong: found $nums, expected $expected"
6223 }
6224 run_test 56n "check lfs find -type l"
6225
6226 test_56o() {
6227         local dir=$DIR/$tdir
6228
6229         setup_56 $dir $NUMFILES $NUMDIRS
6230         utime $dir/file1 > /dev/null || error "utime (1)"
6231         utime $dir/file2 > /dev/null || error "utime (2)"
6232         utime $dir/dir1 > /dev/null || error "utime (3)"
6233         utime $dir/dir2 > /dev/null || error "utime (4)"
6234         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6235         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6236
6237         local expected=4
6238         local nums=$($LFS find -mtime +0 $dir | wc -l)
6239
6240         [ $nums -eq $expected ] ||
6241                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6242
6243         expected=12
6244         cmd="$LFS find -mtime 0 $dir"
6245         nums=$($cmd | wc -l)
6246         [ $nums -eq $expected ] ||
6247                 error "'$cmd' wrong: found $nums, expected $expected"
6248 }
6249 run_test 56o "check lfs find -mtime for old files"
6250
6251 test_56ob() {
6252         local dir=$DIR/$tdir
6253         local expected=1
6254         local count=0
6255
6256         # just to make sure there is something that won't be found
6257         test_mkdir $dir
6258         touch $dir/$tfile.now
6259
6260         for age in year week day hour min; do
6261                 count=$((count + 1))
6262
6263                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6264                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6265                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6266
6267                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6268                 local nums=$($cmd | wc -l)
6269                 [ $nums -eq $expected ] ||
6270                         error "'$cmd' wrong: found $nums, expected $expected"
6271
6272                 cmd="$LFS find $dir -atime $count${age:0:1}"
6273                 nums=$($cmd | wc -l)
6274                 [ $nums -eq $expected ] ||
6275                         error "'$cmd' wrong: found $nums, expected $expected"
6276         done
6277
6278         sleep 2
6279         cmd="$LFS find $dir -ctime +1s -type f"
6280         nums=$($cmd | wc -l)
6281         (( $nums == $count * 2 + 1)) ||
6282                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6283 }
6284 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6285
6286 test_newerXY_base() {
6287         local x=$1
6288         local y=$2
6289         local dir=$DIR/$tdir
6290         local ref
6291         local negref
6292
6293         if [ $y == "t" ]; then
6294                 if [ $x == "b" ]; then
6295                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6296                 else
6297                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6298                 fi
6299         else
6300                 ref=$DIR/$tfile.newer.$x$y
6301                 touch $ref || error "touch $ref failed"
6302         fi
6303
6304         echo "before = $ref"
6305         sleep 2
6306         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6307         sleep 2
6308         if [ $y == "t" ]; then
6309                 if [ $x == "b" ]; then
6310                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6311                 else
6312                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6313                 fi
6314         else
6315                 negref=$DIR/$tfile.negnewer.$x$y
6316                 touch $negref || error "touch $negref failed"
6317         fi
6318
6319         echo "after = $negref"
6320         local cmd="$LFS find $dir -newer$x$y $ref"
6321         local nums=$(eval $cmd | wc -l)
6322         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6323
6324         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6325                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6326
6327         cmd="$LFS find $dir ! -newer$x$y $negref"
6328         nums=$(eval $cmd | wc -l)
6329         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6330                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6331
6332         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6333         nums=$(eval $cmd | wc -l)
6334         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6335                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6336
6337         rm -rf $DIR/*
6338 }
6339
6340 test_56oc() {
6341         test_newerXY_base "a" "a"
6342         test_newerXY_base "a" "m"
6343         test_newerXY_base "a" "c"
6344         test_newerXY_base "m" "a"
6345         test_newerXY_base "m" "m"
6346         test_newerXY_base "m" "c"
6347         test_newerXY_base "c" "a"
6348         test_newerXY_base "c" "m"
6349         test_newerXY_base "c" "c"
6350
6351         [[ -n "$sles_version" ]] &&
6352                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6353
6354         test_newerXY_base "a" "t"
6355         test_newerXY_base "m" "t"
6356         test_newerXY_base "c" "t"
6357
6358         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6359            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6360                 ! btime_supported && echo "btime unsupported" && return 0
6361
6362         test_newerXY_base "b" "b"
6363         test_newerXY_base "b" "t"
6364 }
6365 run_test 56oc "check lfs find -newerXY work"
6366
6367 btime_supported() {
6368         local dir=$DIR/$tdir
6369         local rc
6370
6371         mkdir -p $dir
6372         touch $dir/$tfile
6373         $LFS find $dir -btime -1d -type f
6374         rc=$?
6375         rm -rf $dir
6376         return $rc
6377 }
6378
6379 test_56od() {
6380         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6381                 ! btime_supported && skip "btime unsupported on MDS"
6382
6383         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6384                 ! btime_supported && skip "btime unsupported on clients"
6385
6386         local dir=$DIR/$tdir
6387         local ref=$DIR/$tfile.ref
6388         local negref=$DIR/$tfile.negref
6389
6390         mkdir $dir || error "mkdir $dir failed"
6391         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6392         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6393         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6394         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6395         touch $ref || error "touch $ref failed"
6396         # sleep 3 seconds at least
6397         sleep 3
6398
6399         local before=$(do_facet mds1 date +%s)
6400         local skew=$(($(date +%s) - before + 1))
6401
6402         if (( skew < 0 && skew > -5 )); then
6403                 sleep $((0 - skew + 1))
6404                 skew=0
6405         fi
6406
6407         # Set the dir stripe params to limit files all on MDT0,
6408         # otherwise we need to calc the max clock skew between
6409         # the client and MDTs.
6410         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6411         sleep 2
6412         touch $negref || error "touch $negref failed"
6413
6414         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6415         local nums=$($cmd | wc -l)
6416         local expected=$(((NUMFILES + 1) * NUMDIRS))
6417
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420
6421         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6422         nums=$($cmd | wc -l)
6423         expected=$((NUMFILES + 1))
6424         [ $nums -eq $expected ] ||
6425                 error "'$cmd' wrong: found $nums, expected $expected"
6426
6427         [ $skew -lt 0 ] && return
6428
6429         local after=$(do_facet mds1 date +%s)
6430         local age=$((after - before + 1 + skew))
6431
6432         cmd="$LFS find $dir -btime -${age}s -type f"
6433         nums=$($cmd | wc -l)
6434         expected=$(((NUMFILES + 1) * NUMDIRS))
6435
6436         echo "Clock skew between client and server: $skew, age:$age"
6437         [ $nums -eq $expected ] ||
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439
6440         expected=$(($NUMDIRS + 1))
6441         cmd="$LFS find $dir -btime -${age}s -type d"
6442         nums=$($cmd | wc -l)
6443         [ $nums -eq $expected ] ||
6444                 error "'$cmd' wrong: found $nums, expected $expected"
6445         rm -f $ref $negref || error "Failed to remove $ref $negref"
6446 }
6447 run_test 56od "check lfs find -btime with units"
6448
6449 test_56p() {
6450         [ $RUNAS_ID -eq $UID ] &&
6451                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6452
6453         local dir=$DIR/$tdir
6454
6455         setup_56 $dir $NUMFILES $NUMDIRS
6456         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6457
6458         local expected=$NUMFILES
6459         local cmd="$LFS find -uid $RUNAS_ID $dir"
6460         local nums=$($cmd | wc -l)
6461
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6466         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6467         nums=$($cmd | wc -l)
6468         [ $nums -eq $expected ] ||
6469                 error "'$cmd' wrong: found $nums, expected $expected"
6470 }
6471 run_test 56p "check lfs find -uid and ! -uid"
6472
6473 test_56q() {
6474         [ $RUNAS_ID -eq $UID ] &&
6475                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6476
6477         local dir=$DIR/$tdir
6478
6479         setup_56 $dir $NUMFILES $NUMDIRS
6480         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6481
6482         local expected=$NUMFILES
6483         local cmd="$LFS find -gid $RUNAS_GID $dir"
6484         local nums=$($cmd | wc -l)
6485
6486         [ $nums -eq $expected ] ||
6487                 error "'$cmd' wrong: found $nums, expected $expected"
6488
6489         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6490         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6491         nums=$($cmd | wc -l)
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494 }
6495 run_test 56q "check lfs find -gid and ! -gid"
6496
6497 test_56r() {
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS
6501
6502         local expected=12
6503         local cmd="$LFS find -size 0 -type f -lazy $dir"
6504         local nums=$($cmd | wc -l)
6505
6506         [ $nums -eq $expected ] ||
6507                 error "'$cmd' wrong: found $nums, expected $expected"
6508         cmd="$LFS find -size 0 -type f $dir"
6509         nums=$($cmd | wc -l)
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512
6513         expected=0
6514         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6515         nums=$($cmd | wc -l)
6516         [ $nums -eq $expected ] ||
6517                 error "'$cmd' wrong: found $nums, expected $expected"
6518         cmd="$LFS find ! -size 0 -type f $dir"
6519         nums=$($cmd | wc -l)
6520         [ $nums -eq $expected ] ||
6521                 error "'$cmd' wrong: found $nums, expected $expected"
6522
6523         echo "test" > $dir/$tfile
6524         echo "test2" > $dir/$tfile.2 && sync
6525         expected=1
6526         cmd="$LFS find -size 5 -type f -lazy $dir"
6527         nums=$($cmd | wc -l)
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530         cmd="$LFS find -size 5 -type f $dir"
6531         nums=$($cmd | wc -l)
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534
6535         expected=1
6536         cmd="$LFS find -size +5 -type f -lazy $dir"
6537         nums=$($cmd | wc -l)
6538         [ $nums -eq $expected ] ||
6539                 error "'$cmd' wrong: found $nums, expected $expected"
6540         cmd="$LFS find -size +5 -type f $dir"
6541         nums=$($cmd | wc -l)
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544
6545         expected=2
6546         cmd="$LFS find -size +0 -type f -lazy $dir"
6547         nums=$($cmd | wc -l)
6548         [ $nums -eq $expected ] ||
6549                 error "'$cmd' wrong: found $nums, expected $expected"
6550         cmd="$LFS find -size +0 -type f $dir"
6551         nums=$($cmd | wc -l)
6552         [ $nums -eq $expected ] ||
6553                 error "'$cmd' wrong: found $nums, expected $expected"
6554
6555         expected=2
6556         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6557         nums=$($cmd | wc -l)
6558         [ $nums -eq $expected ] ||
6559                 error "'$cmd' wrong: found $nums, expected $expected"
6560         cmd="$LFS find ! -size -5 -type f $dir"
6561         nums=$($cmd | wc -l)
6562         [ $nums -eq $expected ] ||
6563                 error "'$cmd' wrong: found $nums, expected $expected"
6564
6565         expected=12
6566         cmd="$LFS find -size -5 -type f -lazy $dir"
6567         nums=$($cmd | wc -l)
6568         [ $nums -eq $expected ] ||
6569                 error "'$cmd' wrong: found $nums, expected $expected"
6570         cmd="$LFS find -size -5 -type f $dir"
6571         nums=$($cmd | wc -l)
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574 }
6575 run_test 56r "check lfs find -size works"
6576
6577 test_56ra_sub() {
6578         local expected=$1
6579         local glimpses=$2
6580         local cmd="$3"
6581
6582         cancel_lru_locks $OSC
6583
6584         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6585         local nums=$($cmd | wc -l)
6586
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589
6590         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6591
6592         if (( rpcs_before + glimpses != rpcs_after )); then
6593                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6594                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6595
6596                 if [[ $glimpses == 0 ]]; then
6597                         error "'$cmd' should not send glimpse RPCs to OST"
6598                 else
6599                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6600                 fi
6601         fi
6602 }
6603
6604 test_56ra() {
6605         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6606                 skip "MDS < 2.12.58 doesn't return LSOM data"
6607         local dir=$DIR/$tdir
6608         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6609
6610         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6611
6612         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6613         $LCTL set_param -n llite.*.statahead_agl=0
6614         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6615
6616         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6617         # open and close all files to ensure LSOM is updated
6618         cancel_lru_locks $OSC
6619         find $dir -type f | xargs cat > /dev/null
6620
6621         #   expect_found  glimpse_rpcs  command_to_run
6622         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6623         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6624         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6625         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6626
6627         echo "test" > $dir/$tfile
6628         echo "test2" > $dir/$tfile.2 && sync
6629         cancel_lru_locks $OSC
6630         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6631
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         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6635         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6636
6637         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6638         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6639         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6641         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6642         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6643 }
6644 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6645
6646 test_56rb() {
6647         local dir=$DIR/$tdir
6648         local tmp=$TMP/$tfile.log
6649         local mdt_idx;
6650
6651         test_mkdir -p $dir || error "failed to mkdir $dir"
6652         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6653                 error "failed to setstripe $dir/$tfile"
6654         mdt_idx=$($LFS getdirstripe -i $dir)
6655         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6656
6657         stack_trap "rm -f $tmp" EXIT
6658         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6659         ! grep -q obd_uuid $tmp ||
6660                 error "failed to find --size +100K --ost 0 $dir"
6661         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6662         ! grep -q obd_uuid $tmp ||
6663                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6664 }
6665 run_test 56rb "check lfs find --size --ost/--mdt works"
6666
6667 test_56s() { # LU-611 #LU-9369
6668         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6669
6670         local dir=$DIR/$tdir
6671         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6672
6673         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6674         for i in $(seq $NUMDIRS); do
6675                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6676         done
6677
6678         local expected=$NUMDIRS
6679         local cmd="$LFS find -c $OSTCOUNT $dir"
6680         local nums=$($cmd | wc -l)
6681
6682         [ $nums -eq $expected ] || {
6683                 $LFS getstripe -R $dir
6684                 error "'$cmd' wrong: found $nums, expected $expected"
6685         }
6686
6687         expected=$((NUMDIRS + onestripe))
6688         cmd="$LFS find -stripe-count +0 -type f $dir"
6689         nums=$($cmd | wc -l)
6690         [ $nums -eq $expected ] || {
6691                 $LFS getstripe -R $dir
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693         }
6694
6695         expected=$onestripe
6696         cmd="$LFS find -stripe-count 1 -type f $dir"
6697         nums=$($cmd | wc -l)
6698         [ $nums -eq $expected ] || {
6699                 $LFS getstripe -R $dir
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701         }
6702
6703         cmd="$LFS find -stripe-count -2 -type f $dir"
6704         nums=$($cmd | wc -l)
6705         [ $nums -eq $expected ] || {
6706                 $LFS getstripe -R $dir
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708         }
6709
6710         expected=0
6711         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6712         nums=$($cmd | wc -l)
6713         [ $nums -eq $expected ] || {
6714                 $LFS getstripe -R $dir
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         }
6717 }
6718 run_test 56s "check lfs find -stripe-count works"
6719
6720 test_56t() { # LU-611 #LU-9369
6721         local dir=$DIR/$tdir
6722
6723         setup_56 $dir 0 $NUMDIRS
6724         for i in $(seq $NUMDIRS); do
6725                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6726         done
6727
6728         local expected=$NUMDIRS
6729         local cmd="$LFS find -S 8M $dir"
6730         local nums=$($cmd | wc -l)
6731
6732         [ $nums -eq $expected ] || {
6733                 $LFS getstripe -R $dir
6734                 error "'$cmd' wrong: found $nums, expected $expected"
6735         }
6736         rm -rf $dir
6737
6738         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6739
6740         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6741
6742         expected=$(((NUMDIRS + 1) * NUMFILES))
6743         cmd="$LFS find -stripe-size 512k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747
6748         cmd="$LFS find -stripe-size +320k -type f $dir"
6749         nums=$($cmd | wc -l)
6750         [ $nums -eq $expected ] ||
6751                 error "'$cmd' wrong: found $nums, expected $expected"
6752
6753         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6754         cmd="$LFS find -stripe-size +200k -type f $dir"
6755         nums=$($cmd | wc -l)
6756         [ $nums -eq $expected ] ||
6757                 error "'$cmd' wrong: found $nums, expected $expected"
6758
6759         cmd="$LFS find -stripe-size -640k -type f $dir"
6760         nums=$($cmd | wc -l)
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763
6764         expected=4
6765         cmd="$LFS find -stripe-size 256k -type f $dir"
6766         nums=$($cmd | wc -l)
6767         [ $nums -eq $expected ] ||
6768                 error "'$cmd' wrong: found $nums, expected $expected"
6769
6770         cmd="$LFS find -stripe-size -320k -type f $dir"
6771         nums=$($cmd | wc -l)
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         expected=0
6776         cmd="$LFS find -stripe-size 1024k -type f $dir"
6777         nums=$($cmd | wc -l)
6778         [ $nums -eq $expected ] ||
6779                 error "'$cmd' wrong: found $nums, expected $expected"
6780 }
6781 run_test 56t "check lfs find -stripe-size works"
6782
6783 test_56u() { # LU-611
6784         local dir=$DIR/$tdir
6785
6786         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6787
6788         if [[ $OSTCOUNT -gt 1 ]]; then
6789                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6790                 onestripe=4
6791         else
6792                 onestripe=0
6793         fi
6794
6795         local expected=$(((NUMDIRS + 1) * NUMFILES))
6796         local cmd="$LFS find -stripe-index 0 -type f $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         expected=$onestripe
6803         cmd="$LFS find -stripe-index 1 -type f $dir"
6804         nums=$($cmd | wc -l)
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807
6808         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812
6813         expected=0
6814         # This should produce an error and not return any files
6815         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6816         nums=$($cmd 2>/dev/null | wc -l)
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6822                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6823                 nums=$($cmd | wc -l)
6824                 [ $nums -eq $expected ] ||
6825                         error "'$cmd' wrong: found $nums, expected $expected"
6826         fi
6827 }
6828 run_test 56u "check lfs find -stripe-index works"
6829
6830 test_56v() {
6831         local mdt_idx=0
6832         local dir=$DIR/$tdir
6833
6834         setup_56 $dir $NUMFILES $NUMDIRS
6835
6836         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6837         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6838
6839         for file in $($LFS find -m $UUID $dir); do
6840                 file_midx=$($LFS getstripe -m $file)
6841                 [ $file_midx -eq $mdt_idx ] ||
6842                         error "lfs find -m $UUID != getstripe -m $file_midx"
6843         done
6844 }
6845 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6846
6847 test_56w() {
6848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6850
6851         local dir=$DIR/$tdir
6852
6853         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6854
6855         local stripe_size=$($LFS getstripe -S -d $dir) ||
6856                 error "$LFS getstripe -S -d $dir failed"
6857         stripe_size=${stripe_size%% *}
6858
6859         local file_size=$((stripe_size * OSTCOUNT))
6860         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6861         local required_space=$((file_num * file_size))
6862         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6863                            head -n1)
6864         [[ $free_space -le $((required_space / 1024)) ]] &&
6865                 skip_env "need $required_space, have $free_space kbytes"
6866
6867         local dd_bs=65536
6868         local dd_count=$((file_size / dd_bs))
6869
6870         # write data into the files
6871         local i
6872         local j
6873         local file
6874
6875         for i in $(seq $NUMFILES); do
6876                 file=$dir/file$i
6877                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6878                         error "write data into $file failed"
6879         done
6880         for i in $(seq $NUMDIRS); do
6881                 for j in $(seq $NUMFILES); do
6882                         file=$dir/dir$i/file$j
6883                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6884                                 error "write data into $file failed"
6885                 done
6886         done
6887
6888         # $LFS_MIGRATE will fail if hard link migration is unsupported
6889         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6890                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6891                         error "creating links to $dir/dir1/file1 failed"
6892         fi
6893
6894         local expected=-1
6895
6896         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6897
6898         # lfs_migrate file
6899         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6900
6901         echo "$cmd"
6902         eval $cmd || error "$cmd failed"
6903
6904         check_stripe_count $dir/file1 $expected
6905
6906         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6907         then
6908                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6909                 # OST 1 if it is on OST 0. This file is small enough to
6910                 # be on only one stripe.
6911                 file=$dir/migr_1_ost
6912                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6913                         error "write data into $file failed"
6914                 local obdidx=$($LFS getstripe -i $file)
6915                 local oldmd5=$(md5sum $file)
6916                 local newobdidx=0
6917
6918                 [[ $obdidx -eq 0 ]] && newobdidx=1
6919                 cmd="$LFS migrate -i $newobdidx $file"
6920                 echo $cmd
6921                 eval $cmd || error "$cmd failed"
6922
6923                 local realobdix=$($LFS getstripe -i $file)
6924                 local newmd5=$(md5sum $file)
6925
6926                 [[ $newobdidx -ne $realobdix ]] &&
6927                         error "new OST is different (was=$obdidx, "\
6928                               "wanted=$newobdidx, got=$realobdix)"
6929                 [[ "$oldmd5" != "$newmd5" ]] &&
6930                         error "md5sum differ: $oldmd5, $newmd5"
6931         fi
6932
6933         # lfs_migrate dir
6934         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6935         echo "$cmd"
6936         eval $cmd || error "$cmd failed"
6937
6938         for j in $(seq $NUMFILES); do
6939                 check_stripe_count $dir/dir1/file$j $expected
6940         done
6941
6942         # lfs_migrate works with lfs find
6943         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6944              $LFS_MIGRATE -y -c $expected"
6945         echo "$cmd"
6946         eval $cmd || error "$cmd failed"
6947
6948         for i in $(seq 2 $NUMFILES); do
6949                 check_stripe_count $dir/file$i $expected
6950         done
6951         for i in $(seq 2 $NUMDIRS); do
6952                 for j in $(seq $NUMFILES); do
6953                 check_stripe_count $dir/dir$i/file$j $expected
6954                 done
6955         done
6956 }
6957 run_test 56w "check lfs_migrate -c stripe_count works"
6958
6959 test_56wb() {
6960         local file1=$DIR/$tdir/file1
6961         local create_pool=false
6962         local initial_pool=$($LFS getstripe -p $DIR)
6963         local pool_list=()
6964         local pool=""
6965
6966         echo -n "Creating test dir..."
6967         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6968         echo "done."
6969
6970         echo -n "Creating test file..."
6971         touch $file1 || error "cannot create file"
6972         echo "done."
6973
6974         echo -n "Detecting existing pools..."
6975         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6976
6977         if [ ${#pool_list[@]} -gt 0 ]; then
6978                 echo "${pool_list[@]}"
6979                 for thispool in "${pool_list[@]}"; do
6980                         if [[ -z "$initial_pool" ||
6981                               "$initial_pool" != "$thispool" ]]; then
6982                                 pool="$thispool"
6983                                 echo "Using existing pool '$pool'"
6984                                 break
6985                         fi
6986                 done
6987         else
6988                 echo "none detected."
6989         fi
6990         if [ -z "$pool" ]; then
6991                 pool=${POOL:-testpool}
6992                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6993                 echo -n "Creating pool '$pool'..."
6994                 create_pool=true
6995                 pool_add $pool &> /dev/null ||
6996                         error "pool_add failed"
6997                 echo "done."
6998
6999                 echo -n "Adding target to pool..."
7000                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7001                         error "pool_add_targets failed"
7002                 echo "done."
7003         fi
7004
7005         echo -n "Setting pool using -p option..."
7006         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7007                 error "migrate failed rc = $?"
7008         echo "done."
7009
7010         echo -n "Verifying test file is in pool after migrating..."
7011         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7012                 error "file was not migrated to pool $pool"
7013         echo "done."
7014
7015         echo -n "Removing test file from pool '$pool'..."
7016         # "lfs migrate $file" won't remove the file from the pool
7017         # until some striping information is changed.
7018         $LFS migrate -c 1 $file1 &> /dev/null ||
7019                 error "cannot remove from pool"
7020         [ "$($LFS getstripe -p $file1)" ] &&
7021                 error "pool still set"
7022         echo "done."
7023
7024         echo -n "Setting pool using --pool option..."
7025         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7026                 error "migrate failed rc = $?"
7027         echo "done."
7028
7029         # Clean up
7030         rm -f $file1
7031         if $create_pool; then
7032                 destroy_test_pools 2> /dev/null ||
7033                         error "destroy test pools failed"
7034         fi
7035 }
7036 run_test 56wb "check lfs_migrate pool support"
7037
7038 test_56wc() {
7039         local file1="$DIR/$tdir/file1"
7040         local parent_ssize
7041         local parent_scount
7042         local cur_ssize
7043         local cur_scount
7044         local orig_ssize
7045
7046         echo -n "Creating test dir..."
7047         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7048         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7049                 error "cannot set stripe by '-S 1M -c 1'"
7050         echo "done"
7051
7052         echo -n "Setting initial stripe for test file..."
7053         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7054                 error "cannot set stripe"
7055         cur_ssize=$($LFS getstripe -S "$file1")
7056         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7057         echo "done."
7058
7059         # File currently set to -S 512K -c 1
7060
7061         # Ensure -c and -S options are rejected when -R is set
7062         echo -n "Verifying incompatible options are detected..."
7063         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7064                 error "incompatible -c and -R options not detected"
7065         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7066                 error "incompatible -S and -R options not detected"
7067         echo "done."
7068
7069         # Ensure unrecognized options are passed through to 'lfs migrate'
7070         echo -n "Verifying -S option is passed through to lfs migrate..."
7071         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7072                 error "migration failed"
7073         cur_ssize=$($LFS getstripe -S "$file1")
7074         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7075         echo "done."
7076
7077         # File currently set to -S 1M -c 1
7078
7079         # Ensure long options are supported
7080         echo -n "Verifying long options supported..."
7081         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7082                 error "long option without argument not supported"
7083         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7084                 error "long option with argument not supported"
7085         cur_ssize=$($LFS getstripe -S "$file1")
7086         [ $cur_ssize -eq 524288 ] ||
7087                 error "migrate --stripe-size $cur_ssize != 524288"
7088         echo "done."
7089
7090         # File currently set to -S 512K -c 1
7091
7092         if [ "$OSTCOUNT" -gt 1 ]; then
7093                 echo -n "Verifying explicit stripe count can be set..."
7094                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7095                         error "migrate failed"
7096                 cur_scount=$($LFS getstripe -c "$file1")
7097                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7098                 echo "done."
7099         fi
7100
7101         # File currently set to -S 512K -c 1 or -S 512K -c 2
7102
7103         # Ensure parent striping is used if -R is set, and no stripe
7104         # count or size is specified
7105         echo -n "Setting stripe for parent directory..."
7106         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7107                 error "cannot set stripe '-S 2M -c 1'"
7108         echo "done."
7109
7110         echo -n "Verifying restripe option uses parent stripe settings..."
7111         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7112         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7113         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7114                 error "migrate failed"
7115         cur_ssize=$($LFS getstripe -S "$file1")
7116         [ $cur_ssize -eq $parent_ssize ] ||
7117                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7118         cur_scount=$($LFS getstripe -c "$file1")
7119         [ $cur_scount -eq $parent_scount ] ||
7120                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7121         echo "done."
7122
7123         # File currently set to -S 1M -c 1
7124
7125         # Ensure striping is preserved if -R is not set, and no stripe
7126         # count or size is specified
7127         echo -n "Verifying striping size preserved when not specified..."
7128         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7129         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7130                 error "cannot set stripe on parent directory"
7131         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7132                 error "migrate failed"
7133         cur_ssize=$($LFS getstripe -S "$file1")
7134         [ $cur_ssize -eq $orig_ssize ] ||
7135                 error "migrate by default $cur_ssize != $orig_ssize"
7136         echo "done."
7137
7138         # Ensure file name properly detected when final option has no argument
7139         echo -n "Verifying file name properly detected..."
7140         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7141                 error "file name interpreted as option argument"
7142         echo "done."
7143
7144         # Clean up
7145         rm -f "$file1"
7146 }
7147 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7148
7149 test_56wd() {
7150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7151
7152         local file1=$DIR/$tdir/file1
7153
7154         echo -n "Creating test dir..."
7155         test_mkdir $DIR/$tdir || error "cannot create dir"
7156         echo "done."
7157
7158         echo -n "Creating test file..."
7159         touch $file1
7160         echo "done."
7161
7162         # Ensure 'lfs migrate' will fail by using a non-existent option,
7163         # and make sure rsync is not called to recover
7164         echo -n "Make sure --no-rsync option works..."
7165         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7166                 grep -q 'refusing to fall back to rsync' ||
7167                 error "rsync was called with --no-rsync set"
7168         echo "done."
7169
7170         # Ensure rsync is called without trying 'lfs migrate' first
7171         echo -n "Make sure --rsync option works..."
7172         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7173                 grep -q 'falling back to rsync' &&
7174                 error "lfs migrate was called with --rsync set"
7175         echo "done."
7176
7177         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7178         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7179                 grep -q 'at the same time' ||
7180                 error "--rsync and --no-rsync accepted concurrently"
7181         echo "done."
7182
7183         # Clean up
7184         rm -f $file1
7185 }
7186 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7187
7188 test_56we() {
7189         local td=$DIR/$tdir
7190         local tf=$td/$tfile
7191
7192         test_mkdir $td || error "cannot create $td"
7193         touch $tf || error "cannot touch $tf"
7194
7195         echo -n "Make sure --non-direct|-D works..."
7196         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7197                 grep -q "lfs migrate --non-direct" ||
7198                 error "--non-direct option cannot work correctly"
7199         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7200                 grep -q "lfs migrate -D" ||
7201                 error "-D option cannot work correctly"
7202         echo "done."
7203 }
7204 run_test 56we "check lfs_migrate --non-direct|-D support"
7205
7206 test_56x() {
7207         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7208         check_swap_layouts_support
7209
7210         local dir=$DIR/$tdir
7211         local ref1=/etc/passwd
7212         local file1=$dir/file1
7213
7214         test_mkdir $dir || error "creating dir $dir"
7215         $LFS setstripe -c 2 $file1
7216         cp $ref1 $file1
7217         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7218         stripe=$($LFS getstripe -c $file1)
7219         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7220         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7221
7222         # clean up
7223         rm -f $file1
7224 }
7225 run_test 56x "lfs migration support"
7226
7227 test_56xa() {
7228         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7229         check_swap_layouts_support
7230
7231         local dir=$DIR/$tdir/$testnum
7232
7233         test_mkdir -p $dir
7234
7235         local ref1=/etc/passwd
7236         local file1=$dir/file1
7237
7238         $LFS setstripe -c 2 $file1
7239         cp $ref1 $file1
7240         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7241
7242         local stripe=$($LFS getstripe -c $file1)
7243
7244         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7245         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7246
7247         # clean up
7248         rm -f $file1
7249 }
7250 run_test 56xa "lfs migration --block support"
7251
7252 check_migrate_links() {
7253         local dir="$1"
7254         local file1="$dir/file1"
7255         local begin="$2"
7256         local count="$3"
7257         local runas="$4"
7258         local total_count=$(($begin + $count - 1))
7259         local symlink_count=10
7260         local uniq_count=10
7261
7262         if [ ! -f "$file1" ]; then
7263                 echo -n "creating initial file..."
7264                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7265                         error "cannot setstripe initial file"
7266                 echo "done"
7267
7268                 echo -n "creating symlinks..."
7269                 for s in $(seq 1 $symlink_count); do
7270                         ln -s "$file1" "$dir/slink$s" ||
7271                                 error "cannot create symlinks"
7272                 done
7273                 echo "done"
7274
7275                 echo -n "creating nonlinked files..."
7276                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7277                         error "cannot create nonlinked files"
7278                 echo "done"
7279         fi
7280
7281         # create hard links
7282         if [ ! -f "$dir/file$total_count" ]; then
7283                 echo -n "creating hard links $begin:$total_count..."
7284                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7285                         /dev/null || error "cannot create hard links"
7286                 echo "done"
7287         fi
7288
7289         echo -n "checking number of hard links listed in xattrs..."
7290         local fid=$($LFS getstripe -F "$file1")
7291         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7292
7293         echo "${#paths[*]}"
7294         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7295                         skip "hard link list has unexpected size, skipping test"
7296         fi
7297         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7298                         error "link names should exceed xattrs size"
7299         fi
7300
7301         echo -n "migrating files..."
7302         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7303         local rc=$?
7304         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7305         echo "done"
7306
7307         # make sure all links have been properly migrated
7308         echo -n "verifying files..."
7309         fid=$($LFS getstripe -F "$file1") ||
7310                 error "cannot get fid for file $file1"
7311         for i in $(seq 2 $total_count); do
7312                 local fid2=$($LFS getstripe -F $dir/file$i)
7313
7314                 [ "$fid2" == "$fid" ] ||
7315                         error "migrated hard link has mismatched FID"
7316         done
7317
7318         # make sure hard links were properly detected, and migration was
7319         # performed only once for the entire link set; nonlinked files should
7320         # also be migrated
7321         local actual=$(grep -c 'done' <<< "$migrate_out")
7322         local expected=$(($uniq_count + 1))
7323
7324         [ "$actual" -eq  "$expected" ] ||
7325                 error "hard links individually migrated ($actual != $expected)"
7326
7327         # make sure the correct number of hard links are present
7328         local hardlinks=$(stat -c '%h' "$file1")
7329
7330         [ $hardlinks -eq $total_count ] ||
7331                 error "num hard links $hardlinks != $total_count"
7332         echo "done"
7333
7334         return 0
7335 }
7336
7337 test_56xb() {
7338         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7339                 skip "Need MDS version at least 2.10.55"
7340
7341         local dir="$DIR/$tdir"
7342
7343         test_mkdir "$dir" || error "cannot create dir $dir"
7344
7345         echo "testing lfs migrate mode when all links fit within xattrs"
7346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7347
7348         echo "testing rsync mode when all links fit within xattrs"
7349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7350
7351         echo "testing lfs migrate mode when all links do not fit within xattrs"
7352         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7353
7354         echo "testing rsync mode when all links do not fit within xattrs"
7355         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7356
7357         chown -R $RUNAS_ID $dir
7358         echo "testing non-root lfs migrate mode when not all links are in xattr"
7359         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7360
7361         # clean up
7362         rm -rf $dir
7363 }
7364 run_test 56xb "lfs migration hard link support"
7365
7366 test_56xc() {
7367         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7368
7369         local dir="$DIR/$tdir"
7370
7371         test_mkdir "$dir" || error "cannot create dir $dir"
7372
7373         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7374         echo -n "Setting initial stripe for 20MB test file..."
7375         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7376                 error "cannot setstripe 20MB file"
7377         echo "done"
7378         echo -n "Sizing 20MB test file..."
7379         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7380         echo "done"
7381         echo -n "Verifying small file autostripe count is 1..."
7382         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7383                 error "cannot migrate 20MB file"
7384         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7385                 error "cannot get stripe for $dir/20mb"
7386         [ $stripe_count -eq 1 ] ||
7387                 error "unexpected stripe count $stripe_count for 20MB file"
7388         rm -f "$dir/20mb"
7389         echo "done"
7390
7391         # Test 2: File is small enough to fit within the available space on
7392         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7393         # have at least an additional 1KB for each desired stripe for test 3
7394         echo -n "Setting stripe for 1GB test file..."
7395         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7396         echo "done"
7397         echo -n "Sizing 1GB test file..."
7398         # File size is 1GB + 3KB
7399         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7400         echo "done"
7401
7402         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7403         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7404         if (( avail > 524288 * OSTCOUNT )); then
7405                 echo -n "Migrating 1GB file..."
7406                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7407                         error "cannot migrate 1GB file"
7408                 echo "done"
7409                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7410                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7411                         error "cannot getstripe for 1GB file"
7412                 [ $stripe_count -eq 2 ] ||
7413                         error "unexpected stripe count $stripe_count != 2"
7414                 echo "done"
7415         fi
7416
7417         # Test 3: File is too large to fit within the available space on
7418         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7419         if [ $OSTCOUNT -ge 3 ]; then
7420                 # The required available space is calculated as
7421                 # file size (1GB + 3KB) / OST count (3).
7422                 local kb_per_ost=349526
7423
7424                 echo -n "Migrating 1GB file with limit..."
7425                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7426                         error "cannot migrate 1GB file with limit"
7427                 echo "done"
7428
7429                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7430                 echo -n "Verifying 1GB autostripe count with limited space..."
7431                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7432                         error "unexpected stripe count $stripe_count (min 3)"
7433                 echo "done"
7434         fi
7435
7436         # clean up
7437         rm -rf $dir
7438 }
7439 run_test 56xc "lfs migration autostripe"
7440
7441 test_56xd() {
7442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7443
7444         local dir=$DIR/$tdir
7445         local f_mgrt=$dir/$tfile.mgrt
7446         local f_yaml=$dir/$tfile.yaml
7447         local f_copy=$dir/$tfile.copy
7448         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7449         local layout_copy="-c 2 -S 2M -i 1"
7450         local yamlfile=$dir/yamlfile
7451         local layout_before;
7452         local layout_after;
7453
7454         test_mkdir "$dir" || error "cannot create dir $dir"
7455         $LFS setstripe $layout_yaml $f_yaml ||
7456                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7457         $LFS getstripe --yaml $f_yaml > $yamlfile
7458         $LFS setstripe $layout_copy $f_copy ||
7459                 error "cannot setstripe $f_copy with layout $layout_copy"
7460         touch $f_mgrt
7461         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7462
7463         # 1. test option --yaml
7464         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7465                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7466         layout_before=$(get_layout_param $f_yaml)
7467         layout_after=$(get_layout_param $f_mgrt)
7468         [ "$layout_after" == "$layout_before" ] ||
7469                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7470
7471         # 2. test option --copy
7472         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7473                 error "cannot migrate $f_mgrt with --copy $f_copy"
7474         layout_before=$(get_layout_param $f_copy)
7475         layout_after=$(get_layout_param $f_mgrt)
7476         [ "$layout_after" == "$layout_before" ] ||
7477                 error "lfs_migrate --copy: $layout_after != $layout_before"
7478 }
7479 run_test 56xd "check lfs_migrate --yaml and --copy support"
7480
7481 test_56xe() {
7482         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7483
7484         local dir=$DIR/$tdir
7485         local f_comp=$dir/$tfile
7486         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7487         local layout_before=""
7488         local layout_after=""
7489
7490         test_mkdir "$dir" || error "cannot create dir $dir"
7491         $LFS setstripe $layout $f_comp ||
7492                 error "cannot setstripe $f_comp with layout $layout"
7493         layout_before=$(get_layout_param $f_comp)
7494         dd if=/dev/zero of=$f_comp bs=1M count=4
7495
7496         # 1. migrate a comp layout file by lfs_migrate
7497         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7498         layout_after=$(get_layout_param $f_comp)
7499         [ "$layout_before" == "$layout_after" ] ||
7500                 error "lfs_migrate: $layout_before != $layout_after"
7501
7502         # 2. migrate a comp layout file by lfs migrate
7503         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7504         layout_after=$(get_layout_param $f_comp)
7505         [ "$layout_before" == "$layout_after" ] ||
7506                 error "lfs migrate: $layout_before != $layout_after"
7507 }
7508 run_test 56xe "migrate a composite layout file"
7509
7510 test_56xf() {
7511         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7512
7513         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7514                 skip "Need server version at least 2.13.53"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -c1 -E -1 -c2"
7519         local fid_before=""
7520         local fid_after=""
7521
7522         test_mkdir "$dir" || error "cannot create dir $dir"
7523         $LFS setstripe $layout $f_comp ||
7524                 error "cannot setstripe $f_comp with layout $layout"
7525         fid_before=$($LFS getstripe --fid $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file to a comp layout
7529         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7530         fid_after=$($LFS getstripe --fid $f_comp)
7531         [ "$fid_before" == "$fid_after" ] ||
7532                 error "comp-to-comp migrate: $fid_before != $fid_after"
7533
7534         # 2. migrate a comp layout file to a plain layout
7535         $LFS migrate -c2 $f_comp ||
7536                 error "cannot migrate $f_comp by lfs migrate"
7537         fid_after=$($LFS getstripe --fid $f_comp)
7538         [ "$fid_before" == "$fid_after" ] ||
7539                 error "comp-to-plain migrate: $fid_before != $fid_after"
7540
7541         # 3. migrate a plain layout file to a comp layout
7542         $LFS migrate $layout $f_comp ||
7543                 error "cannot migrate $f_comp by lfs migrate"
7544         fid_after=$($LFS getstripe --fid $f_comp)
7545         [ "$fid_before" == "$fid_after" ] ||
7546                 error "plain-to-comp migrate: $fid_before != $fid_after"
7547 }
7548 run_test 56xf "FID is not lost during migration of a composite layout file"
7549
7550 test_56y() {
7551         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7552                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7553
7554         local res=""
7555         local dir=$DIR/$tdir
7556         local f1=$dir/file1
7557         local f2=$dir/file2
7558
7559         test_mkdir -p $dir || error "creating dir $dir"
7560         touch $f1 || error "creating std file $f1"
7561         $MULTIOP $f2 H2c || error "creating released file $f2"
7562
7563         # a directory can be raid0, so ask only for files
7564         res=$($LFS find $dir -L raid0 -type f | wc -l)
7565         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7566
7567         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7568         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7569
7570         # only files can be released, so no need to force file search
7571         res=$($LFS find $dir -L released)
7572         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7573
7574         res=$($LFS find $dir -type f \! -L released)
7575         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7576 }
7577 run_test 56y "lfs find -L raid0|released"
7578
7579 test_56z() { # LU-4824
7580         # This checks to make sure 'lfs find' continues after errors
7581         # There are two classes of errors that should be caught:
7582         # - If multiple paths are provided, all should be searched even if one
7583         #   errors out
7584         # - If errors are encountered during the search, it should not terminate
7585         #   early
7586         local dir=$DIR/$tdir
7587         local i
7588
7589         test_mkdir $dir
7590         for i in d{0..9}; do
7591                 test_mkdir $dir/$i
7592                 touch $dir/$i/$tfile
7593         done
7594         $LFS find $DIR/non_existent_dir $dir &&
7595                 error "$LFS find did not return an error"
7596         # Make a directory unsearchable. This should NOT be the last entry in
7597         # directory order.  Arbitrarily pick the 6th entry
7598         chmod 700 $($LFS find $dir -type d | sed '6!d')
7599
7600         $RUNAS $LFS find $DIR/non_existent $dir
7601         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7602
7603         # The user should be able to see 10 directories and 9 files
7604         (( count == 19 )) ||
7605                 error "$LFS find found $count != 19 entries after error"
7606 }
7607 run_test 56z "lfs find should continue after an error"
7608
7609 test_56aa() { # LU-5937
7610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7611
7612         local dir=$DIR/$tdir
7613
7614         mkdir $dir
7615         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7616
7617         createmany -o $dir/striped_dir/${tfile}- 1024
7618         local dirs=$($LFS find --size +8k $dir/)
7619
7620         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7621 }
7622 run_test 56aa "lfs find --size under striped dir"
7623
7624 test_56ab() { # LU-10705
7625         test_mkdir $DIR/$tdir
7626         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7627         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7628         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7629         # Flush writes to ensure valid blocks.  Need to be more thorough for
7630         # ZFS, since blocks are not allocated/returned to client immediately.
7631         sync_all_data
7632         wait_zfs_commit ost1 2
7633         cancel_lru_locks osc
7634         ls -ls $DIR/$tdir
7635
7636         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7637
7638         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7639
7640         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7641         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7642
7643         rm -f $DIR/$tdir/$tfile.[123]
7644 }
7645 run_test 56ab "lfs find --blocks"
7646
7647 # LU-11188
7648 test_56aca() {
7649         local dir="$DIR/$tdir"
7650         local perms=(001 002 003 004 005 006 007
7651                      010 020 030 040 050 060 070
7652                      100 200 300 400 500 600 700
7653                      111 222 333 444 555 666 777)
7654         local perm_minus=(8 8 4 8 4 4 2
7655                           8 8 4 8 4 4 2
7656                           8 8 4 8 4 4 2
7657                           4 4 2 4 2 2 1)
7658         local perm_slash=(8  8 12  8 12 12 14
7659                           8  8 12  8 12 12 14
7660                           8  8 12  8 12 12 14
7661                          16 16 24 16 24 24 28)
7662
7663         test_mkdir "$dir"
7664         for perm in ${perms[*]}; do
7665                 touch "$dir/$tfile.$perm"
7666                 chmod $perm "$dir/$tfile.$perm"
7667         done
7668
7669         for ((i = 0; i < ${#perms[*]}; i++)); do
7670                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7671                 (( $num == 1 )) ||
7672                         error "lfs find -perm ${perms[i]}:"\
7673                               "$num != 1"
7674
7675                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7676                 (( $num == ${perm_minus[i]} )) ||
7677                         error "lfs find -perm -${perms[i]}:"\
7678                               "$num != ${perm_minus[i]}"
7679
7680                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7681                 (( $num == ${perm_slash[i]} )) ||
7682                         error "lfs find -perm /${perms[i]}:"\
7683                               "$num != ${perm_slash[i]}"
7684         done
7685 }
7686 run_test 56aca "check lfs find -perm with octal representation"
7687
7688 test_56acb() {
7689         local dir=$DIR/$tdir
7690         # p is the permission of write and execute for user, group and other
7691         # without the umask. It is used to test +wx.
7692         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7693         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7694         local symbolic=(+t  a+t u+t g+t o+t
7695                         g+s u+s o+s +s o+sr
7696                         o=r,ug+o,u+w
7697                         u+ g+ o+ a+ ugo+
7698                         u- g- o- a- ugo-
7699                         u= g= o= a= ugo=
7700                         o=r,ug+o,u+w u=r,a+u,u+w
7701                         g=r,ugo=g,u+w u+x,+X +X
7702                         u+x,u+X u+X u+x,g+X o+r,+X
7703                         u+x,go+X +wx +rwx)
7704
7705         test_mkdir $dir
7706         for perm in ${perms[*]}; do
7707                 touch "$dir/$tfile.$perm"
7708                 chmod $perm "$dir/$tfile.$perm"
7709         done
7710
7711         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7712                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7713
7714                 (( $num == 1 )) ||
7715                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7716         done
7717 }
7718 run_test 56acb "check lfs find -perm with symbolic representation"
7719
7720 test_56acc() {
7721         local dir=$DIR/$tdir
7722         local tests="17777 787 789 abcd
7723                 ug=uu ug=a ug=gu uo=ou urw
7724                 u+xg+x a=r,u+x,"
7725
7726         test_mkdir $dir
7727         for err in $tests; do
7728                 if $LFS find $dir -perm $err 2>/dev/null; then
7729                         error "lfs find -perm $err: parsing should have failed"
7730                 fi
7731         done
7732 }
7733 run_test 56acc "check parsing error for lfs find -perm"
7734
7735 test_56ba() {
7736         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7737                 skip "Need MDS version at least 2.10.50"
7738
7739         # Create composite files with one component
7740         local dir=$DIR/$tdir
7741
7742         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7743         # Create composite files with three components
7744         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7745         # Create non-composite files
7746         createmany -o $dir/${tfile}- 10
7747
7748         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7749
7750         [[ $nfiles == 10 ]] ||
7751                 error "lfs find -E 1M found $nfiles != 10 files"
7752
7753         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7754         [[ $nfiles == 25 ]] ||
7755                 error "lfs find ! -E 1M found $nfiles != 25 files"
7756
7757         # All files have a component that starts at 0
7758         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7759         [[ $nfiles == 35 ]] ||
7760                 error "lfs find --component-start 0 - $nfiles != 35 files"
7761
7762         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7763         [[ $nfiles == 15 ]] ||
7764                 error "lfs find --component-start 2M - $nfiles != 15 files"
7765
7766         # All files created here have a componenet that does not starts at 2M
7767         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7768         [[ $nfiles == 35 ]] ||
7769                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7770
7771         # Find files with a specified number of components
7772         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7773         [[ $nfiles == 15 ]] ||
7774                 error "lfs find --component-count 3 - $nfiles != 15 files"
7775
7776         # Remember non-composite files have a component count of zero
7777         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7778         [[ $nfiles == 10 ]] ||
7779                 error "lfs find --component-count 0 - $nfiles != 10 files"
7780
7781         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7782         [[ $nfiles == 20 ]] ||
7783                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7784
7785         # All files have a flag called "init"
7786         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7787         [[ $nfiles == 35 ]] ||
7788                 error "lfs find --component-flags init - $nfiles != 35 files"
7789
7790         # Multi-component files will have a component not initialized
7791         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7792         [[ $nfiles == 15 ]] ||
7793                 error "lfs find !--component-flags init - $nfiles != 15 files"
7794
7795         rm -rf $dir
7796
7797 }
7798 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7799
7800 test_56ca() {
7801         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7802                 skip "Need MDS version at least 2.10.57"
7803
7804         local td=$DIR/$tdir
7805         local tf=$td/$tfile
7806         local dir
7807         local nfiles
7808         local cmd
7809         local i
7810         local j
7811
7812         # create mirrored directories and mirrored files
7813         mkdir $td || error "mkdir $td failed"
7814         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7815         createmany -o $tf- 10 || error "create $tf- failed"
7816
7817         for i in $(seq 2); do
7818                 dir=$td/dir$i
7819                 mkdir $dir || error "mkdir $dir failed"
7820                 $LFS mirror create -N$((3 + i)) $dir ||
7821                         error "create mirrored dir $dir failed"
7822                 createmany -o $dir/$tfile- 10 ||
7823                         error "create $dir/$tfile- failed"
7824         done
7825
7826         # change the states of some mirrored files
7827         echo foo > $tf-6
7828         for i in $(seq 2); do
7829                 dir=$td/dir$i
7830                 for j in $(seq 4 9); do
7831                         echo foo > $dir/$tfile-$j
7832                 done
7833         done
7834
7835         # find mirrored files with specific mirror count
7836         cmd="$LFS find --mirror-count 3 --type f $td"
7837         nfiles=$($cmd | wc -l)
7838         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7839
7840         cmd="$LFS find ! --mirror-count 3 --type f $td"
7841         nfiles=$($cmd | wc -l)
7842         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7843
7844         cmd="$LFS find --mirror-count +2 --type f $td"
7845         nfiles=$($cmd | wc -l)
7846         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7847
7848         cmd="$LFS find --mirror-count -6 --type f $td"
7849         nfiles=$($cmd | wc -l)
7850         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7851
7852         # find mirrored files with specific file state
7853         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7854         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7855
7856         cmd="$LFS find --mirror-state=ro --type f $td"
7857         nfiles=$($cmd | wc -l)
7858         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7859
7860         cmd="$LFS find ! --mirror-state=ro --type f $td"
7861         nfiles=$($cmd | wc -l)
7862         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7863
7864         cmd="$LFS find --mirror-state=wp --type f $td"
7865         nfiles=$($cmd | wc -l)
7866         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7867
7868         cmd="$LFS find ! --mirror-state=sp --type f $td"
7869         nfiles=$($cmd | wc -l)
7870         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7871 }
7872 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7873
7874 test_56da() { # LU-14179
7875         local path=$DIR/$tdir
7876
7877         test_mkdir $path
7878         cd $path
7879
7880         local longdir=$(str_repeat 'a' 255)
7881
7882         for i in {1..15}; do
7883                 path=$path/$longdir
7884                 test_mkdir $longdir
7885                 cd $longdir
7886         done
7887
7888         local len=${#path}
7889         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7890
7891         test_mkdir $lastdir
7892         cd $lastdir
7893         # PATH_MAX-1
7894         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7895
7896         # NAME_MAX
7897         touch $(str_repeat 'f' 255)
7898
7899         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7900                 error "lfs find reported an error"
7901
7902         rm -rf $DIR/$tdir
7903 }
7904 run_test 56da "test lfs find with long paths"
7905
7906 test_57a() {
7907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7908         # note test will not do anything if MDS is not local
7909         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7910                 skip_env "ldiskfs only test"
7911         fi
7912         remote_mds_nodsh && skip "remote MDS with nodsh"
7913
7914         local MNTDEV="osd*.*MDT*.mntdev"
7915         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7916         [ -z "$DEV" ] && error "can't access $MNTDEV"
7917         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7918                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7919                         error "can't access $DEV"
7920                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7921                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7922                 rm $TMP/t57a.dump
7923         done
7924 }
7925 run_test 57a "verify MDS filesystem created with large inodes =="
7926
7927 test_57b() {
7928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7929         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7930                 skip_env "ldiskfs only test"
7931         fi
7932         remote_mds_nodsh && skip "remote MDS with nodsh"
7933
7934         local dir=$DIR/$tdir
7935         local filecount=100
7936         local file1=$dir/f1
7937         local fileN=$dir/f$filecount
7938
7939         rm -rf $dir || error "removing $dir"
7940         test_mkdir -c1 $dir
7941         local mdtidx=$($LFS getstripe -m $dir)
7942         local mdtname=MDT$(printf %04x $mdtidx)
7943         local facet=mds$((mdtidx + 1))
7944
7945         echo "mcreating $filecount files"
7946         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7947
7948         # verify that files do not have EAs yet
7949         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7950                 error "$file1 has an EA"
7951         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7952                 error "$fileN has an EA"
7953
7954         sync
7955         sleep 1
7956         df $dir  #make sure we get new statfs data
7957         local mdsfree=$(do_facet $facet \
7958                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7959         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7960         local file
7961
7962         echo "opening files to create objects/EAs"
7963         for file in $(seq -f $dir/f%g 1 $filecount); do
7964                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7965                         error "opening $file"
7966         done
7967
7968         # verify that files have EAs now
7969         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7970         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7971
7972         sleep 1  #make sure we get new statfs data
7973         df $dir
7974         local mdsfree2=$(do_facet $facet \
7975                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7976         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7977
7978         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7979                 if [ "$mdsfree" != "$mdsfree2" ]; then
7980                         error "MDC before $mdcfree != after $mdcfree2"
7981                 else
7982                         echo "MDC before $mdcfree != after $mdcfree2"
7983                         echo "unable to confirm if MDS has large inodes"
7984                 fi
7985         fi
7986         rm -rf $dir
7987 }
7988 run_test 57b "default LOV EAs are stored inside large inodes ==="
7989
7990 test_58() {
7991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7992         [ -z "$(which wiretest 2>/dev/null)" ] &&
7993                         skip_env "could not find wiretest"
7994
7995         wiretest
7996 }
7997 run_test 58 "verify cross-platform wire constants =============="
7998
7999 test_59() {
8000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8001
8002         echo "touch 130 files"
8003         createmany -o $DIR/f59- 130
8004         echo "rm 130 files"
8005         unlinkmany $DIR/f59- 130
8006         sync
8007         # wait for commitment of removal
8008         wait_delete_completed
8009 }
8010 run_test 59 "verify cancellation of llog records async ========="
8011
8012 TEST60_HEAD="test_60 run $RANDOM"
8013 test_60a() {
8014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8015         remote_mgs_nodsh && skip "remote MGS with nodsh"
8016         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8017                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8018                         skip_env "missing subtest run-llog.sh"
8019
8020         log "$TEST60_HEAD - from kernel mode"
8021         do_facet mgs "$LCTL dk > /dev/null"
8022         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8023         do_facet mgs $LCTL dk > $TMP/$tfile
8024
8025         # LU-6388: test llog_reader
8026         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8027         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8028         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8029                         skip_env "missing llog_reader"
8030         local fstype=$(facet_fstype mgs)
8031         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8032                 skip_env "Only for ldiskfs or zfs type mgs"
8033
8034         local mntpt=$(facet_mntpt mgs)
8035         local mgsdev=$(mgsdevname 1)
8036         local fid_list
8037         local fid
8038         local rec_list
8039         local rec
8040         local rec_type
8041         local obj_file
8042         local path
8043         local seq
8044         local oid
8045         local pass=true
8046
8047         #get fid and record list
8048         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8049                 tail -n 4))
8050         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8051                 tail -n 4))
8052         #remount mgs as ldiskfs or zfs type
8053         stop mgs || error "stop mgs failed"
8054         mount_fstype mgs || error "remount mgs failed"
8055         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8056                 fid=${fid_list[i]}
8057                 rec=${rec_list[i]}
8058                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8059                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8060                 oid=$((16#$oid))
8061
8062                 case $fstype in
8063                         ldiskfs )
8064                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8065                         zfs )
8066                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8067                 esac
8068                 echo "obj_file is $obj_file"
8069                 do_facet mgs $llog_reader $obj_file
8070
8071                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8072                         awk '{ print $3 }' | sed -e "s/^type=//g")
8073                 if [ $rec_type != $rec ]; then
8074                         echo "FAILED test_60a wrong record type $rec_type," \
8075                               "should be $rec"
8076                         pass=false
8077                         break
8078                 fi
8079
8080                 #check obj path if record type is LLOG_LOGID_MAGIC
8081                 if [ "$rec" == "1064553b" ]; then
8082                         path=$(do_facet mgs $llog_reader $obj_file |
8083                                 grep "path=" | awk '{ print $NF }' |
8084                                 sed -e "s/^path=//g")
8085                         if [ $obj_file != $mntpt/$path ]; then
8086                                 echo "FAILED test_60a wrong obj path" \
8087                                       "$montpt/$path, should be $obj_file"
8088                                 pass=false
8089                                 break
8090                         fi
8091                 fi
8092         done
8093         rm -f $TMP/$tfile
8094         #restart mgs before "error", otherwise it will block the next test
8095         stop mgs || error "stop mgs failed"
8096         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8097         $pass || error "test failed, see FAILED test_60a messages for specifics"
8098 }
8099 run_test 60a "llog_test run from kernel module and test llog_reader"
8100
8101 test_60b() { # bug 6411
8102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8103
8104         dmesg > $DIR/$tfile
8105         LLOG_COUNT=$(do_facet mgs dmesg |
8106                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8107                           /llog_[a-z]*.c:[0-9]/ {
8108                                 if (marker)
8109                                         from_marker++
8110                                 from_begin++
8111                           }
8112                           END {
8113                                 if (marker)
8114                                         print from_marker
8115                                 else
8116                                         print from_begin
8117                           }")
8118
8119         [[ $LLOG_COUNT -gt 120 ]] &&
8120                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8121 }
8122 run_test 60b "limit repeated messages from CERROR/CWARN"
8123
8124 test_60c() {
8125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8126
8127         echo "create 5000 files"
8128         createmany -o $DIR/f60c- 5000
8129 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8130         lctl set_param fail_loc=0x80000137
8131         unlinkmany $DIR/f60c- 5000
8132         lctl set_param fail_loc=0
8133 }
8134 run_test 60c "unlink file when mds full"
8135
8136 test_60d() {
8137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8138
8139         SAVEPRINTK=$(lctl get_param -n printk)
8140         # verify "lctl mark" is even working"
8141         MESSAGE="test message ID $RANDOM $$"
8142         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8143         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8144
8145         lctl set_param printk=0 || error "set lnet.printk failed"
8146         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8147         MESSAGE="new test message ID $RANDOM $$"
8148         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8149         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8150         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8151
8152         lctl set_param -n printk="$SAVEPRINTK"
8153 }
8154 run_test 60d "test printk console message masking"
8155
8156 test_60e() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158         remote_mds_nodsh && skip "remote MDS with nodsh"
8159
8160         touch $DIR/$tfile
8161 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8162         do_facet mds1 lctl set_param fail_loc=0x15b
8163         rm $DIR/$tfile
8164 }
8165 run_test 60e "no space while new llog is being created"
8166
8167 test_60f() {
8168         local old_path=$($LCTL get_param -n debug_path)
8169
8170         stack_trap "$LCTL set_param debug_path=$old_path"
8171         stack_trap "rm -f $TMP/$tfile*"
8172         rm -f $TMP/$tfile* 2> /dev/null
8173         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8174         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8175         test_mkdir $DIR/$tdir
8176         # retry in case the open is cached and not released
8177         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8178                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8179                 sleep 0.1
8180         done
8181         ls $TMP/$tfile*
8182         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8183 }
8184 run_test 60f "change debug_path works"
8185
8186 test_60g() {
8187         local pid
8188         local i
8189
8190         test_mkdir -c $MDSCOUNT $DIR/$tdir
8191
8192         (
8193                 local index=0
8194                 while true; do
8195                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8196                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8197                                 2>/dev/null
8198                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8199                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8200                         index=$((index + 1))
8201                 done
8202         ) &
8203
8204         pid=$!
8205
8206         for i in {0..100}; do
8207                 # define OBD_FAIL_OSD_TXN_START    0x19a
8208                 local index=$((i % MDSCOUNT + 1))
8209
8210                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8211                         > /dev/null
8212                 sleep 0.01
8213         done
8214
8215         kill -9 $pid
8216
8217         for i in $(seq $MDSCOUNT); do
8218                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8219         done
8220
8221         mkdir $DIR/$tdir/new || error "mkdir failed"
8222         rmdir $DIR/$tdir/new || error "rmdir failed"
8223
8224         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8225                 -t namespace
8226         for i in $(seq $MDSCOUNT); do
8227                 wait_update_facet mds$i "$LCTL get_param -n \
8228                         mdd.$(facet_svc mds$i).lfsck_namespace |
8229                         awk '/^status/ { print \\\$2 }'" "completed"
8230         done
8231
8232         ls -R $DIR/$tdir || error "ls failed"
8233         rm -rf $DIR/$tdir || error "rmdir failed"
8234 }
8235 run_test 60g "transaction abort won't cause MDT hung"
8236
8237 test_60h() {
8238         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8239                 skip "Need MDS version at least 2.12.52"
8240         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8241
8242         local f
8243
8244         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8245         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8246         for fail_loc in 0x80000188 0x80000189; do
8247                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8248                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8249                         error "mkdir $dir-$fail_loc failed"
8250                 for i in {0..10}; do
8251                         # create may fail on missing stripe
8252                         echo $i > $DIR/$tdir-$fail_loc/$i
8253                 done
8254                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8255                         error "getdirstripe $tdir-$fail_loc failed"
8256                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8257                         error "migrate $tdir-$fail_loc failed"
8258                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8259                         error "getdirstripe $tdir-$fail_loc failed"
8260                 pushd $DIR/$tdir-$fail_loc
8261                 for f in *; do
8262                         echo $f | cmp $f - || error "$f data mismatch"
8263                 done
8264                 popd
8265                 rm -rf $DIR/$tdir-$fail_loc
8266         done
8267 }
8268 run_test 60h "striped directory with missing stripes can be accessed"
8269
8270 test_61a() {
8271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8272
8273         f="$DIR/f61"
8274         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8275         cancel_lru_locks osc
8276         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8277         sync
8278 }
8279 run_test 61a "mmap() writes don't make sync hang ================"
8280
8281 test_61b() {
8282         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8283 }
8284 run_test 61b "mmap() of unstriped file is successful"
8285
8286 # bug 2330 - insufficient obd_match error checking causes LBUG
8287 test_62() {
8288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8289
8290         f="$DIR/f62"
8291         echo foo > $f
8292         cancel_lru_locks osc
8293         lctl set_param fail_loc=0x405
8294         cat $f && error "cat succeeded, expect -EIO"
8295         lctl set_param fail_loc=0
8296 }
8297 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8298 # match every page all of the time.
8299 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8300
8301 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8302 # Though this test is irrelevant anymore, it helped to reveal some
8303 # other grant bugs (LU-4482), let's keep it.
8304 test_63a() {   # was test_63
8305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8306
8307         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8308
8309         for i in `seq 10` ; do
8310                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8311                 sleep 5
8312                 kill $!
8313                 sleep 1
8314         done
8315
8316         rm -f $DIR/f63 || true
8317 }
8318 run_test 63a "Verify oig_wait interruption does not crash ======="
8319
8320 # bug 2248 - async write errors didn't return to application on sync
8321 # bug 3677 - async write errors left page locked
8322 test_63b() {
8323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8324
8325         debugsave
8326         lctl set_param debug=-1
8327
8328         # ensure we have a grant to do async writes
8329         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8330         rm $DIR/$tfile
8331
8332         sync    # sync lest earlier test intercept the fail_loc
8333
8334         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8335         lctl set_param fail_loc=0x80000406
8336         $MULTIOP $DIR/$tfile Owy && \
8337                 error "sync didn't return ENOMEM"
8338         sync; sleep 2; sync     # do a real sync this time to flush page
8339         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8340                 error "locked page left in cache after async error" || true
8341         debugrestore
8342 }
8343 run_test 63b "async write errors should be returned to fsync ==="
8344
8345 test_64a () {
8346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8347
8348         lfs df $DIR
8349         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8350 }
8351 run_test 64a "verify filter grant calculations (in kernel) ====="
8352
8353 test_64b () {
8354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8355
8356         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8357 }
8358 run_test 64b "check out-of-space detection on client"
8359
8360 test_64c() {
8361         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8362 }
8363 run_test 64c "verify grant shrink"
8364
8365 import_param() {
8366         local tgt=$1
8367         local param=$2
8368
8369         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8370 }
8371
8372 # this does exactly what osc_request.c:osc_announce_cached() does in
8373 # order to calculate max amount of grants to ask from server
8374 want_grant() {
8375         local tgt=$1
8376
8377         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8378         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8379
8380         ((rpc_in_flight++));
8381         nrpages=$((nrpages * rpc_in_flight))
8382
8383         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8384
8385         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8386
8387         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8388         local undirty=$((nrpages * PAGE_SIZE))
8389
8390         local max_extent_pages
8391         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8392         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8393         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8394         local grant_extent_tax
8395         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8396
8397         undirty=$((undirty + nrextents * grant_extent_tax))
8398
8399         echo $undirty
8400 }
8401
8402 # this is size of unit for grant allocation. It should be equal to
8403 # what tgt_grant.c:tgt_grant_chunk() calculates
8404 grant_chunk() {
8405         local tgt=$1
8406         local max_brw_size
8407         local grant_extent_tax
8408
8409         max_brw_size=$(import_param $tgt max_brw_size)
8410
8411         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8412
8413         echo $(((max_brw_size + grant_extent_tax) * 2))
8414 }
8415
8416 test_64d() {
8417         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8418                 skip "OST < 2.10.55 doesn't limit grants enough"
8419
8420         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8421
8422         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8423                 skip "no grant_param connect flag"
8424
8425         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8426
8427         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8428         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8429
8430
8431         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8432         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8433
8434         $LFS setstripe $DIR/$tfile -i 0 -c 1
8435         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8436         ddpid=$!
8437
8438         while kill -0 $ddpid; do
8439                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8440
8441                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8442                         kill $ddpid
8443                         error "cur_grant $cur_grant > $max_cur_granted"
8444                 fi
8445
8446                 sleep 1
8447         done
8448 }
8449 run_test 64d "check grant limit exceed"
8450
8451 check_grants() {
8452         local tgt=$1
8453         local expected=$2
8454         local msg=$3
8455         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8456
8457         ((cur_grants == expected)) ||
8458                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8459 }
8460
8461 round_up_p2() {
8462         echo $((($1 + $2 - 1) & ~($2 - 1)))
8463 }
8464
8465 test_64e() {
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8468                 skip "Need OSS version at least 2.11.56"
8469
8470         # Remount client to reset grant
8471         remount_client $MOUNT || error "failed to remount client"
8472         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8473
8474         local init_grants=$(import_param $osc_tgt initial_grant)
8475
8476         check_grants $osc_tgt $init_grants "init grants"
8477
8478         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8479         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8480         local gbs=$(import_param $osc_tgt grant_block_size)
8481
8482         # write random number of bytes from max_brw_size / 4 to max_brw_size
8483         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8484         # align for direct io
8485         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8486         # round to grant consumption unit
8487         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8488
8489         local grants=$((wb_round_up + extent_tax))
8490
8491         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8492
8493         # define OBD_FAIL_TGT_NO_GRANT 0x725
8494         # make the server not grant more back
8495         do_facet ost1 $LCTL set_param fail_loc=0x725
8496         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8497
8498         do_facet ost1 $LCTL set_param fail_loc=0
8499
8500         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8501
8502         rm -f $DIR/$tfile || error "rm failed"
8503
8504         # Remount client to reset grant
8505         remount_client $MOUNT || error "failed to remount client"
8506         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8507
8508         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8509
8510         # define OBD_FAIL_TGT_NO_GRANT 0x725
8511         # make the server not grant more back
8512         do_facet ost1 $LCTL set_param fail_loc=0x725
8513         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8514         do_facet ost1 $LCTL set_param fail_loc=0
8515
8516         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8517 }
8518 run_test 64e "check grant consumption (no grant allocation)"
8519
8520 test_64f() {
8521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8522
8523         # Remount client to reset grant
8524         remount_client $MOUNT || error "failed to remount client"
8525         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8526
8527         local init_grants=$(import_param $osc_tgt initial_grant)
8528         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8529         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8530         local gbs=$(import_param $osc_tgt grant_block_size)
8531         local chunk=$(grant_chunk $osc_tgt)
8532
8533         # write random number of bytes from max_brw_size / 4 to max_brw_size
8534         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8535         # align for direct io
8536         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8537         # round to grant consumption unit
8538         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8539
8540         local grants=$((wb_round_up + extent_tax))
8541
8542         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8543         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8544                 error "error writing to $DIR/$tfile"
8545
8546         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8547                 "direct io with grant allocation"
8548
8549         rm -f $DIR/$tfile || error "rm failed"
8550
8551         # Remount client to reset grant
8552         remount_client $MOUNT || error "failed to remount client"
8553         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8554
8555         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8556
8557         local cmd="oO_WRONLY:w${write_bytes}_yc"
8558
8559         $MULTIOP $DIR/$tfile $cmd &
8560         MULTIPID=$!
8561         sleep 1
8562
8563         check_grants $osc_tgt $((init_grants - grants)) \
8564                 "buffered io, not write rpc"
8565
8566         kill -USR1 $MULTIPID
8567         wait
8568
8569         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8570                 "buffered io, one RPC"
8571 }
8572 run_test 64f "check grant consumption (with grant allocation)"
8573
8574 # bug 1414 - set/get directories' stripe info
8575 test_65a() {
8576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8577
8578         test_mkdir $DIR/$tdir
8579         touch $DIR/$tdir/f1
8580         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8581 }
8582 run_test 65a "directory with no stripe info"
8583
8584 test_65b() {
8585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8586
8587         test_mkdir $DIR/$tdir
8588         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8589
8590         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8591                                                 error "setstripe"
8592         touch $DIR/$tdir/f2
8593         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8594 }
8595 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8596
8597 test_65c() {
8598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8599         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8600
8601         test_mkdir $DIR/$tdir
8602         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8603
8604         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8605                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8606         touch $DIR/$tdir/f3
8607         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8608 }
8609 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8610
8611 test_65d() {
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         test_mkdir $DIR/$tdir
8615         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8616         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8617
8618         if [[ $STRIPECOUNT -le 0 ]]; then
8619                 sc=1
8620         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8621                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8622                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8623         else
8624                 sc=$(($STRIPECOUNT - 1))
8625         fi
8626         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8627         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8628         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8629                 error "lverify failed"
8630 }
8631 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8632
8633 test_65e() {
8634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8635
8636         test_mkdir $DIR/$tdir
8637
8638         $LFS setstripe $DIR/$tdir || error "setstripe"
8639         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8640                                         error "no stripe info failed"
8641         touch $DIR/$tdir/f6
8642         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8643 }
8644 run_test 65e "directory setstripe defaults"
8645
8646 test_65f() {
8647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8648
8649         test_mkdir $DIR/${tdir}f
8650         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8651                 error "setstripe succeeded" || true
8652 }
8653 run_test 65f "dir setstripe permission (should return error) ==="
8654
8655 test_65g() {
8656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8657
8658         test_mkdir $DIR/$tdir
8659         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8660
8661         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8662                 error "setstripe -S failed"
8663         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8664         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8665                 error "delete default stripe failed"
8666 }
8667 run_test 65g "directory setstripe -d"
8668
8669 test_65h() {
8670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8671
8672         test_mkdir $DIR/$tdir
8673         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8674
8675         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8676                 error "setstripe -S failed"
8677         test_mkdir $DIR/$tdir/dd1
8678         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8679                 error "stripe info inherit failed"
8680 }
8681 run_test 65h "directory stripe info inherit ===================="
8682
8683 test_65i() {
8684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8685
8686         save_layout_restore_at_exit $MOUNT
8687
8688         # bug6367: set non-default striping on root directory
8689         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8690
8691         # bug12836: getstripe on -1 default directory striping
8692         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8693
8694         # bug12836: getstripe -v on -1 default directory striping
8695         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8696
8697         # bug12836: new find on -1 default directory striping
8698         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8699 }
8700 run_test 65i "various tests to set root directory striping"
8701
8702 test_65j() { # bug6367
8703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8704
8705         sync; sleep 1
8706
8707         # if we aren't already remounting for each test, do so for this test
8708         if [ "$I_MOUNTED" = "yes" ]; then
8709                 cleanup || error "failed to unmount"
8710                 setup
8711         fi
8712
8713         save_layout_restore_at_exit $MOUNT
8714
8715         $LFS setstripe -d $MOUNT || error "setstripe failed"
8716 }
8717 run_test 65j "set default striping on root directory (bug 6367)="
8718
8719 cleanup_65k() {
8720         rm -rf $DIR/$tdir
8721         wait_delete_completed
8722         do_facet $SINGLEMDS "lctl set_param -n \
8723                 osp.$ost*MDT0000.max_create_count=$max_count"
8724         do_facet $SINGLEMDS "lctl set_param -n \
8725                 osp.$ost*MDT0000.create_count=$count"
8726         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8727         echo $INACTIVE_OSC "is Activate"
8728
8729         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8730 }
8731
8732 test_65k() { # bug11679
8733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8735         remote_mds_nodsh && skip "remote MDS with nodsh"
8736
8737         local disable_precreate=true
8738         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8739                 disable_precreate=false
8740
8741         echo "Check OST status: "
8742         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8743                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8744
8745         for OSC in $MDS_OSCS; do
8746                 echo $OSC "is active"
8747                 do_facet $SINGLEMDS lctl --device %$OSC activate
8748         done
8749
8750         for INACTIVE_OSC in $MDS_OSCS; do
8751                 local ost=$(osc_to_ost $INACTIVE_OSC)
8752                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8753                                lov.*md*.target_obd |
8754                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8755
8756                 mkdir -p $DIR/$tdir
8757                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8758                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8759
8760                 echo "Deactivate: " $INACTIVE_OSC
8761                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8762
8763                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8764                               osp.$ost*MDT0000.create_count")
8765                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8766                                   osp.$ost*MDT0000.max_create_count")
8767                 $disable_precreate &&
8768                         do_facet $SINGLEMDS "lctl set_param -n \
8769                                 osp.$ost*MDT0000.max_create_count=0"
8770
8771                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8772                         [ -f $DIR/$tdir/$idx ] && continue
8773                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8774                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8775                                 { cleanup_65k;
8776                                   error "setstripe $idx should succeed"; }
8777                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8778                 done
8779                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8780                 rmdir $DIR/$tdir
8781
8782                 do_facet $SINGLEMDS "lctl set_param -n \
8783                         osp.$ost*MDT0000.max_create_count=$max_count"
8784                 do_facet $SINGLEMDS "lctl set_param -n \
8785                         osp.$ost*MDT0000.create_count=$count"
8786                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8787                 echo $INACTIVE_OSC "is Activate"
8788
8789                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8790         done
8791 }
8792 run_test 65k "validate manual striping works properly with deactivated OSCs"
8793
8794 test_65l() { # bug 12836
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796
8797         test_mkdir -p $DIR/$tdir/test_dir
8798         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8799         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8800 }
8801 run_test 65l "lfs find on -1 stripe dir ========================"
8802
8803 test_65m() {
8804         local layout=$(save_layout $MOUNT)
8805         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8806                 restore_layout $MOUNT $layout
8807                 error "setstripe should fail by non-root users"
8808         }
8809         true
8810 }
8811 run_test 65m "normal user can't set filesystem default stripe"
8812
8813 test_65n() {
8814         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8815         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8816                 skip "Need MDS version at least 2.12.50"
8817         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8818
8819         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8820         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8821         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8822
8823         local root_layout=$(save_layout $MOUNT)
8824         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8825
8826         # new subdirectory under root directory should not inherit
8827         # the default layout from root
8828         local dir1=$MOUNT/$tdir-1
8829         mkdir $dir1 || error "mkdir $dir1 failed"
8830         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8831                 error "$dir1 shouldn't have LOV EA"
8832
8833         # delete the default layout on root directory
8834         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8835
8836         local dir2=$MOUNT/$tdir-2
8837         mkdir $dir2 || error "mkdir $dir2 failed"
8838         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8839                 error "$dir2 shouldn't have LOV EA"
8840
8841         # set a new striping pattern on root directory
8842         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8843         local new_def_stripe_size=$((def_stripe_size * 2))
8844         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8845                 error "set stripe size on $MOUNT failed"
8846
8847         # new file created in $dir2 should inherit the new stripe size from
8848         # the filesystem default
8849         local file2=$dir2/$tfile-2
8850         touch $file2 || error "touch $file2 failed"
8851
8852         local file2_stripe_size=$($LFS getstripe -S $file2)
8853         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8854         {
8855                 echo "file2_stripe_size: '$file2_stripe_size'"
8856                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8857                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8858         }
8859
8860         local dir3=$MOUNT/$tdir-3
8861         mkdir $dir3 || error "mkdir $dir3 failed"
8862         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8863         # the root layout, which is the actual default layout that will be used
8864         # when new files are created in $dir3.
8865         local dir3_layout=$(get_layout_param $dir3)
8866         local root_dir_layout=$(get_layout_param $MOUNT)
8867         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8868         {
8869                 echo "dir3_layout: '$dir3_layout'"
8870                 echo "root_dir_layout: '$root_dir_layout'"
8871                 error "$dir3 should show the default layout from $MOUNT"
8872         }
8873
8874         # set OST pool on root directory
8875         local pool=$TESTNAME
8876         pool_add $pool || error "add $pool failed"
8877         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8878                 error "add targets to $pool failed"
8879
8880         $LFS setstripe -p $pool $MOUNT ||
8881                 error "set OST pool on $MOUNT failed"
8882
8883         # new file created in $dir3 should inherit the pool from
8884         # the filesystem default
8885         local file3=$dir3/$tfile-3
8886         touch $file3 || error "touch $file3 failed"
8887
8888         local file3_pool=$($LFS getstripe -p $file3)
8889         [[ "$file3_pool" = "$pool" ]] ||
8890                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8891
8892         local dir4=$MOUNT/$tdir-4
8893         mkdir $dir4 || error "mkdir $dir4 failed"
8894         local dir4_layout=$(get_layout_param $dir4)
8895         root_dir_layout=$(get_layout_param $MOUNT)
8896         echo "$LFS getstripe -d $dir4"
8897         $LFS getstripe -d $dir4
8898         echo "$LFS getstripe -d $MOUNT"
8899         $LFS getstripe -d $MOUNT
8900         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8901         {
8902                 echo "dir4_layout: '$dir4_layout'"
8903                 echo "root_dir_layout: '$root_dir_layout'"
8904                 error "$dir4 should show the default layout from $MOUNT"
8905         }
8906
8907         # new file created in $dir4 should inherit the pool from
8908         # the filesystem default
8909         local file4=$dir4/$tfile-4
8910         touch $file4 || error "touch $file4 failed"
8911
8912         local file4_pool=$($LFS getstripe -p $file4)
8913         [[ "$file4_pool" = "$pool" ]] ||
8914                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8915
8916         # new subdirectory under non-root directory should inherit
8917         # the default layout from its parent directory
8918         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8919                 error "set directory layout on $dir4 failed"
8920
8921         local dir5=$dir4/$tdir-5
8922         mkdir $dir5 || error "mkdir $dir5 failed"
8923
8924         dir4_layout=$(get_layout_param $dir4)
8925         local dir5_layout=$(get_layout_param $dir5)
8926         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8927         {
8928                 echo "dir4_layout: '$dir4_layout'"
8929                 echo "dir5_layout: '$dir5_layout'"
8930                 error "$dir5 should inherit the default layout from $dir4"
8931         }
8932
8933         # though subdir under ROOT doesn't inherit default layout, but
8934         # its sub dir/file should be created with default layout.
8935         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8936         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8937                 skip "Need MDS version at least 2.12.59"
8938
8939         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8940         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8941         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8942
8943         if [ $default_lmv_hash == "none" ]; then
8944                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8945         else
8946                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8947                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8948         fi
8949
8950         $LFS setdirstripe -D -c 2 $MOUNT ||
8951                 error "setdirstripe -D -c 2 failed"
8952         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8953         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8954         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8955 }
8956 run_test 65n "don't inherit default layout from root for new subdirectories"
8957
8958 # bug 2543 - update blocks count on client
8959 test_66() {
8960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8961
8962         COUNT=${COUNT:-8}
8963         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8964         sync; sync_all_data; sync; sync_all_data
8965         cancel_lru_locks osc
8966         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8967         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8968 }
8969 run_test 66 "update inode blocks count on client ==============="
8970
8971 meminfo() {
8972         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8973 }
8974
8975 swap_used() {
8976         swapon -s | awk '($1 == "'$1'") { print $4 }'
8977 }
8978
8979 # bug5265, obdfilter oa2dentry return -ENOENT
8980 # #define OBD_FAIL_SRV_ENOENT 0x217
8981 test_69() {
8982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8983         remote_ost_nodsh && skip "remote OST with nodsh"
8984
8985         f="$DIR/$tfile"
8986         $LFS setstripe -c 1 -i 0 $f
8987
8988         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8989
8990         do_facet ost1 lctl set_param fail_loc=0x217
8991         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8992         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8993
8994         do_facet ost1 lctl set_param fail_loc=0
8995         $DIRECTIO write $f 0 2 || error "write error"
8996
8997         cancel_lru_locks osc
8998         $DIRECTIO read $f 0 1 || error "read error"
8999
9000         do_facet ost1 lctl set_param fail_loc=0x217
9001         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9002
9003         do_facet ost1 lctl set_param fail_loc=0
9004         rm -f $f
9005 }
9006 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9007
9008 test_71() {
9009         test_mkdir $DIR/$tdir
9010         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9011         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9012 }
9013 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9014
9015 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9017         [ "$RUNAS_ID" = "$UID" ] &&
9018                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9019         # Check that testing environment is properly set up. Skip if not
9020         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9021                 skip_env "User $RUNAS_ID does not exist - skipping"
9022
9023         touch $DIR/$tfile
9024         chmod 777 $DIR/$tfile
9025         chmod ug+s $DIR/$tfile
9026         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9027                 error "$RUNAS dd $DIR/$tfile failed"
9028         # See if we are still setuid/sgid
9029         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9030                 error "S/gid is not dropped on write"
9031         # Now test that MDS is updated too
9032         cancel_lru_locks mdc
9033         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9034                 error "S/gid is not dropped on MDS"
9035         rm -f $DIR/$tfile
9036 }
9037 run_test 72a "Test that remove suid works properly (bug5695) ===="
9038
9039 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9040         local perm
9041
9042         [ "$RUNAS_ID" = "$UID" ] &&
9043                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9044         [ "$RUNAS_ID" -eq 0 ] &&
9045                 skip_env "RUNAS_ID = 0 -- skipping"
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047         # Check that testing environment is properly set up. Skip if not
9048         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9049                 skip_env "User $RUNAS_ID does not exist - skipping"
9050
9051         touch $DIR/${tfile}-f{g,u}
9052         test_mkdir $DIR/${tfile}-dg
9053         test_mkdir $DIR/${tfile}-du
9054         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9055         chmod g+s $DIR/${tfile}-{f,d}g
9056         chmod u+s $DIR/${tfile}-{f,d}u
9057         for perm in 777 2777 4777; do
9058                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9059                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9060                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9061                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9062         done
9063         true
9064 }
9065 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9066
9067 # bug 3462 - multiple simultaneous MDC requests
9068 test_73() {
9069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9070
9071         test_mkdir $DIR/d73-1
9072         test_mkdir $DIR/d73-2
9073         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9074         pid1=$!
9075
9076         lctl set_param fail_loc=0x80000129
9077         $MULTIOP $DIR/d73-1/f73-2 Oc &
9078         sleep 1
9079         lctl set_param fail_loc=0
9080
9081         $MULTIOP $DIR/d73-2/f73-3 Oc &
9082         pid3=$!
9083
9084         kill -USR1 $pid1
9085         wait $pid1 || return 1
9086
9087         sleep 25
9088
9089         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9090         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9091         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9092
9093         rm -rf $DIR/d73-*
9094 }
9095 run_test 73 "multiple MDC requests (should not deadlock)"
9096
9097 test_74a() { # bug 6149, 6184
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099
9100         touch $DIR/f74a
9101         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9102         #
9103         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9104         # will spin in a tight reconnection loop
9105         $LCTL set_param fail_loc=0x8000030e
9106         # get any lock that won't be difficult - lookup works.
9107         ls $DIR/f74a
9108         $LCTL set_param fail_loc=0
9109         rm -f $DIR/f74a
9110         true
9111 }
9112 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9113
9114 test_74b() { # bug 13310
9115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9116
9117         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9118         #
9119         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9120         # will spin in a tight reconnection loop
9121         $LCTL set_param fail_loc=0x8000030e
9122         # get a "difficult" lock
9123         touch $DIR/f74b
9124         $LCTL set_param fail_loc=0
9125         rm -f $DIR/f74b
9126         true
9127 }
9128 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9129
9130 test_74c() {
9131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9132
9133         #define OBD_FAIL_LDLM_NEW_LOCK
9134         $LCTL set_param fail_loc=0x319
9135         touch $DIR/$tfile && error "touch successful"
9136         $LCTL set_param fail_loc=0
9137         true
9138 }
9139 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9140
9141 slab_lic=/sys/kernel/slab/lustre_inode_cache
9142 num_objects() {
9143         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9144         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9145                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9146 }
9147
9148 test_76a() { # Now for b=20433, added originally in b=1443
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150
9151         cancel_lru_locks osc
9152         # there may be some slab objects cached per core
9153         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9154         local before=$(num_objects)
9155         local count=$((512 * cpus))
9156         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9157         local margin=$((count / 10))
9158         if [[ -f $slab_lic/aliases ]]; then
9159                 local aliases=$(cat $slab_lic/aliases)
9160                 (( aliases > 0 )) && margin=$((margin * aliases))
9161         fi
9162
9163         echo "before slab objects: $before"
9164         for i in $(seq $count); do
9165                 touch $DIR/$tfile
9166                 rm -f $DIR/$tfile
9167         done
9168         cancel_lru_locks osc
9169         local after=$(num_objects)
9170         echo "created: $count, after slab objects: $after"
9171         # shared slab counts are not very accurate, allow significant margin
9172         # the main goal is that the cache growth is not permanently > $count
9173         while (( after > before + margin )); do
9174                 sleep 1
9175                 after=$(num_objects)
9176                 wait=$((wait + 1))
9177                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9178                 if (( wait > 60 )); then
9179                         error "inode slab grew from $before+$margin to $after"
9180                 fi
9181         done
9182 }
9183 run_test 76a "confirm clients recycle inodes properly ===="
9184
9185 test_76b() {
9186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9187         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9188
9189         local count=512
9190         local before=$(num_objects)
9191
9192         for i in $(seq $count); do
9193                 mkdir $DIR/$tdir
9194                 rmdir $DIR/$tdir
9195         done
9196
9197         local after=$(num_objects)
9198         local wait=0
9199
9200         while (( after > before )); do
9201                 sleep 1
9202                 after=$(num_objects)
9203                 wait=$((wait + 1))
9204                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9205                 if (( wait > 60 )); then
9206                         error "inode slab grew from $before to $after"
9207                 fi
9208         done
9209
9210         echo "slab objects before: $before, after: $after"
9211 }
9212 run_test 76b "confirm clients recycle directory inodes properly ===="
9213
9214 export ORIG_CSUM=""
9215 set_checksums()
9216 {
9217         # Note: in sptlrpc modes which enable its own bulk checksum, the
9218         # original crc32_le bulk checksum will be automatically disabled,
9219         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9220         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9221         # In this case set_checksums() will not be no-op, because sptlrpc
9222         # bulk checksum will be enabled all through the test.
9223
9224         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9225         lctl set_param -n osc.*.checksums $1
9226         return 0
9227 }
9228
9229 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9230                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9231 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9232                              tr -d [] | head -n1)}
9233 set_checksum_type()
9234 {
9235         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9236         rc=$?
9237         log "set checksum type to $1, rc = $rc"
9238         return $rc
9239 }
9240
9241 get_osc_checksum_type()
9242 {
9243         # arugment 1: OST name, like OST0000
9244         ost=$1
9245         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9246                         sed 's/.*\[\(.*\)\].*/\1/g')
9247         rc=$?
9248         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9249         echo $checksum_type
9250 }
9251
9252 F77_TMP=$TMP/f77-temp
9253 F77SZ=8
9254 setup_f77() {
9255         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9256                 error "error writing to $F77_TMP"
9257 }
9258
9259 test_77a() { # bug 10889
9260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9261         $GSS && skip_env "could not run with gss"
9262
9263         [ ! -f $F77_TMP ] && setup_f77
9264         set_checksums 1
9265         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9266         set_checksums 0
9267         rm -f $DIR/$tfile
9268 }
9269 run_test 77a "normal checksum read/write operation"
9270
9271 test_77b() { # bug 10889
9272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9273         $GSS && skip_env "could not run with gss"
9274
9275         [ ! -f $F77_TMP ] && setup_f77
9276         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9277         $LCTL set_param fail_loc=0x80000409
9278         set_checksums 1
9279
9280         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9281                 error "dd error: $?"
9282         $LCTL set_param fail_loc=0
9283
9284         for algo in $CKSUM_TYPES; do
9285                 cancel_lru_locks osc
9286                 set_checksum_type $algo
9287                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9288                 $LCTL set_param fail_loc=0x80000408
9289                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9290                 $LCTL set_param fail_loc=0
9291         done
9292         set_checksums 0
9293         set_checksum_type $ORIG_CSUM_TYPE
9294         rm -f $DIR/$tfile
9295 }
9296 run_test 77b "checksum error on client write, read"
9297
9298 cleanup_77c() {
9299         trap 0
9300         set_checksums 0
9301         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9302         $check_ost &&
9303                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9304         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9305         $check_ost && [ -n "$ost_file_prefix" ] &&
9306                 do_facet ost1 rm -f ${ost_file_prefix}\*
9307 }
9308
9309 test_77c() {
9310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9311         $GSS && skip_env "could not run with gss"
9312         remote_ost_nodsh && skip "remote OST with nodsh"
9313
9314         local bad1
9315         local osc_file_prefix
9316         local osc_file
9317         local check_ost=false
9318         local ost_file_prefix
9319         local ost_file
9320         local orig_cksum
9321         local dump_cksum
9322         local fid
9323
9324         # ensure corruption will occur on first OSS/OST
9325         $LFS setstripe -i 0 $DIR/$tfile
9326
9327         [ ! -f $F77_TMP ] && setup_f77
9328         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9329                 error "dd write error: $?"
9330         fid=$($LFS path2fid $DIR/$tfile)
9331
9332         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9333         then
9334                 check_ost=true
9335                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9336                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9337         else
9338                 echo "OSS do not support bulk pages dump upon error"
9339         fi
9340
9341         osc_file_prefix=$($LCTL get_param -n debug_path)
9342         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9343
9344         trap cleanup_77c EXIT
9345
9346         set_checksums 1
9347         # enable bulk pages dump upon error on Client
9348         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9349         # enable bulk pages dump upon error on OSS
9350         $check_ost &&
9351                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9352
9353         # flush Client cache to allow next read to reach OSS
9354         cancel_lru_locks osc
9355
9356         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9357         $LCTL set_param fail_loc=0x80000408
9358         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9359         $LCTL set_param fail_loc=0
9360
9361         rm -f $DIR/$tfile
9362
9363         # check cksum dump on Client
9364         osc_file=$(ls ${osc_file_prefix}*)
9365         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9366         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9367         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9368         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9369         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9370                      cksum)
9371         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9372         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9373                 error "dump content does not match on Client"
9374
9375         $check_ost || skip "No need to check cksum dump on OSS"
9376
9377         # check cksum dump on OSS
9378         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9379         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9380         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9381         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9382         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9383                 error "dump content does not match on OSS"
9384
9385         cleanup_77c
9386 }
9387 run_test 77c "checksum error on client read with debug"
9388
9389 test_77d() { # bug 10889
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391         $GSS && skip_env "could not run with gss"
9392
9393         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9394         $LCTL set_param fail_loc=0x80000409
9395         set_checksums 1
9396         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9397                 error "direct write: rc=$?"
9398         $LCTL set_param fail_loc=0
9399         set_checksums 0
9400
9401         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9402         $LCTL set_param fail_loc=0x80000408
9403         set_checksums 1
9404         cancel_lru_locks osc
9405         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9406                 error "direct read: rc=$?"
9407         $LCTL set_param fail_loc=0
9408         set_checksums 0
9409 }
9410 run_test 77d "checksum error on OST direct write, read"
9411
9412 test_77f() { # bug 10889
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9414         $GSS && skip_env "could not run with gss"
9415
9416         set_checksums 1
9417         for algo in $CKSUM_TYPES; do
9418                 cancel_lru_locks osc
9419                 set_checksum_type $algo
9420                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9421                 $LCTL set_param fail_loc=0x409
9422                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9423                         error "direct write succeeded"
9424                 $LCTL set_param fail_loc=0
9425         done
9426         set_checksum_type $ORIG_CSUM_TYPE
9427         set_checksums 0
9428 }
9429 run_test 77f "repeat checksum error on write (expect error)"
9430
9431 test_77g() { # bug 10889
9432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9433         $GSS && skip_env "could not run with gss"
9434         remote_ost_nodsh && skip "remote OST with nodsh"
9435
9436         [ ! -f $F77_TMP ] && setup_f77
9437
9438         local file=$DIR/$tfile
9439         stack_trap "rm -f $file" EXIT
9440
9441         $LFS setstripe -c 1 -i 0 $file
9442         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9443         do_facet ost1 lctl set_param fail_loc=0x8000021a
9444         set_checksums 1
9445         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9446                 error "write error: rc=$?"
9447         do_facet ost1 lctl set_param fail_loc=0
9448         set_checksums 0
9449
9450         cancel_lru_locks osc
9451         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9452         do_facet ost1 lctl set_param fail_loc=0x8000021b
9453         set_checksums 1
9454         cmp $F77_TMP $file || error "file compare failed"
9455         do_facet ost1 lctl set_param fail_loc=0
9456         set_checksums 0
9457 }
9458 run_test 77g "checksum error on OST write, read"
9459
9460 test_77k() { # LU-10906
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462         $GSS && skip_env "could not run with gss"
9463
9464         local cksum_param="osc.$FSNAME*.checksums"
9465         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9466         local checksum
9467         local i
9468
9469         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9470         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9471         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9472
9473         for i in 0 1; do
9474                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9475                         error "failed to set checksum=$i on MGS"
9476                 wait_update $HOSTNAME "$get_checksum" $i
9477                 #remount
9478                 echo "remount client, checksum should be $i"
9479                 remount_client $MOUNT || error "failed to remount client"
9480                 checksum=$(eval $get_checksum)
9481                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9482         done
9483         # remove persistent param to avoid races with checksum mountopt below
9484         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9485                 error "failed to delete checksum on MGS"
9486
9487         for opt in "checksum" "nochecksum"; do
9488                 #remount with mount option
9489                 echo "remount client with option $opt, checksum should be $i"
9490                 umount_client $MOUNT || error "failed to umount client"
9491                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9492                         error "failed to mount client with option '$opt'"
9493                 checksum=$(eval $get_checksum)
9494                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9495                 i=$((i - 1))
9496         done
9497
9498         remount_client $MOUNT || error "failed to remount client"
9499 }
9500 run_test 77k "enable/disable checksum correctly"
9501
9502 test_77l() {
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504         $GSS && skip_env "could not run with gss"
9505
9506         set_checksums 1
9507         stack_trap "set_checksums $ORIG_CSUM" EXIT
9508         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9509
9510         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9511
9512         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9513         for algo in $CKSUM_TYPES; do
9514                 set_checksum_type $algo || error "fail to set checksum type $algo"
9515                 osc_algo=$(get_osc_checksum_type OST0000)
9516                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9517
9518                 # no locks, no reqs to let the connection idle
9519                 cancel_lru_locks osc
9520                 lru_resize_disable osc
9521                 wait_osc_import_state client ost1 IDLE
9522
9523                 # ensure ost1 is connected
9524                 stat $DIR/$tfile >/dev/null || error "can't stat"
9525                 wait_osc_import_state client ost1 FULL
9526
9527                 osc_algo=$(get_osc_checksum_type OST0000)
9528                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9529         done
9530         return 0
9531 }
9532 run_test 77l "preferred checksum type is remembered after reconnected"
9533
9534 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9535 rm -f $F77_TMP
9536 unset F77_TMP
9537
9538 cleanup_test_78() {
9539         trap 0
9540         rm -f $DIR/$tfile
9541 }
9542
9543 test_78() { # bug 10901
9544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9545         remote_ost || skip_env "local OST"
9546
9547         NSEQ=5
9548         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9549         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9550         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9551         echo "MemTotal: $MEMTOTAL"
9552
9553         # reserve 256MB of memory for the kernel and other running processes,
9554         # and then take 1/2 of the remaining memory for the read/write buffers.
9555         if [ $MEMTOTAL -gt 512 ] ;then
9556                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9557         else
9558                 # for those poor memory-starved high-end clusters...
9559                 MEMTOTAL=$((MEMTOTAL / 2))
9560         fi
9561         echo "Mem to use for directio: $MEMTOTAL"
9562
9563         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9564         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9565         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9566         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9567                 head -n1)
9568         echo "Smallest OST: $SMALLESTOST"
9569         [[ $SMALLESTOST -lt 10240 ]] &&
9570                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9571
9572         trap cleanup_test_78 EXIT
9573
9574         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9575                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9576
9577         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9578         echo "File size: $F78SIZE"
9579         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9580         for i in $(seq 1 $NSEQ); do
9581                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9582                 echo directIO rdwr round $i of $NSEQ
9583                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9584         done
9585
9586         cleanup_test_78
9587 }
9588 run_test 78 "handle large O_DIRECT writes correctly ============"
9589
9590 test_79() { # bug 12743
9591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9592
9593         wait_delete_completed
9594
9595         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9596         BKFREE=$(calc_osc_kbytes kbytesfree)
9597         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9598
9599         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9600         DFTOTAL=`echo $STRING | cut -d, -f1`
9601         DFUSED=`echo $STRING  | cut -d, -f2`
9602         DFAVAIL=`echo $STRING | cut -d, -f3`
9603         DFFREE=$(($DFTOTAL - $DFUSED))
9604
9605         ALLOWANCE=$((64 * $OSTCOUNT))
9606
9607         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9608            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9609                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9610         fi
9611         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9612            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9613                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9614         fi
9615         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9616            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9617                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9618         fi
9619 }
9620 run_test 79 "df report consistency check ======================="
9621
9622 test_80() { # bug 10718
9623         remote_ost_nodsh && skip "remote OST with nodsh"
9624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9625
9626         # relax strong synchronous semantics for slow backends like ZFS
9627         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9628                 local soc="obdfilter.*.sync_lock_cancel"
9629                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9630
9631                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9632                 if [ -z "$save" ]; then
9633                         soc="obdfilter.*.sync_on_lock_cancel"
9634                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9635                 fi
9636
9637                 if [ "$save" != "never" ]; then
9638                         local hosts=$(comma_list $(osts_nodes))
9639
9640                         do_nodes $hosts $LCTL set_param $soc=never
9641                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9642                 fi
9643         fi
9644
9645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9646         sync; sleep 1; sync
9647         local before=$(date +%s)
9648         cancel_lru_locks osc
9649         local after=$(date +%s)
9650         local diff=$((after - before))
9651         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9652
9653         rm -f $DIR/$tfile
9654 }
9655 run_test 80 "Page eviction is equally fast at high offsets too"
9656
9657 test_81a() { # LU-456
9658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9659         remote_ost_nodsh && skip "remote OST with nodsh"
9660
9661         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9662         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9663         do_facet ost1 lctl set_param fail_loc=0x80000228
9664
9665         # write should trigger a retry and success
9666         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9667         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9668         RC=$?
9669         if [ $RC -ne 0 ] ; then
9670                 error "write should success, but failed for $RC"
9671         fi
9672 }
9673 run_test 81a "OST should retry write when get -ENOSPC ==============="
9674
9675 test_81b() { # LU-456
9676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9677         remote_ost_nodsh && skip "remote OST with nodsh"
9678
9679         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9680         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9681         do_facet ost1 lctl set_param fail_loc=0x228
9682
9683         # write should retry several times and return -ENOSPC finally
9684         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9685         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9686         RC=$?
9687         ENOSPC=28
9688         if [ $RC -ne $ENOSPC ] ; then
9689                 error "dd should fail for -ENOSPC, but succeed."
9690         fi
9691 }
9692 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9693
9694 test_99() {
9695         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9696
9697         test_mkdir $DIR/$tdir.cvsroot
9698         chown $RUNAS_ID $DIR/$tdir.cvsroot
9699
9700         cd $TMP
9701         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9702
9703         cd /etc/init.d
9704         # some versions of cvs import exit(1) when asked to import links or
9705         # files they can't read.  ignore those files.
9706         local toignore=$(find . -type l -printf '-I %f\n' -o \
9707                          ! -perm /4 -printf '-I %f\n')
9708         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9709                 $tdir.reposname vtag rtag
9710
9711         cd $DIR
9712         test_mkdir $DIR/$tdir.reposname
9713         chown $RUNAS_ID $DIR/$tdir.reposname
9714         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9715
9716         cd $DIR/$tdir.reposname
9717         $RUNAS touch foo99
9718         $RUNAS cvs add -m 'addmsg' foo99
9719         $RUNAS cvs update
9720         $RUNAS cvs commit -m 'nomsg' foo99
9721         rm -fr $DIR/$tdir.cvsroot
9722 }
9723 run_test 99 "cvs strange file/directory operations"
9724
9725 test_100() {
9726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9727         [[ "$NETTYPE" =~ tcp ]] ||
9728                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9729         remote_ost_nodsh && skip "remote OST with nodsh"
9730         remote_mds_nodsh && skip "remote MDS with nodsh"
9731         remote_servers ||
9732                 skip "useless for local single node setup"
9733
9734         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9735                 [ "$PROT" != "tcp" ] && continue
9736                 RPORT=$(echo $REMOTE | cut -d: -f2)
9737                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9738
9739                 rc=0
9740                 LPORT=`echo $LOCAL | cut -d: -f2`
9741                 if [ $LPORT -ge 1024 ]; then
9742                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9743                         netstat -tna
9744                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9745                 fi
9746         done
9747         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9748 }
9749 run_test 100 "check local port using privileged port ==========="
9750
9751 function get_named_value()
9752 {
9753     local tag=$1
9754
9755     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9756 }
9757
9758 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9759                    awk '/^max_cached_mb/ { print $2 }')
9760
9761 cleanup_101a() {
9762         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9763         trap 0
9764 }
9765
9766 test_101a() {
9767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9768
9769         local s
9770         local discard
9771         local nreads=10000
9772         local cache_limit=32
9773
9774         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9775         trap cleanup_101a EXIT
9776         $LCTL set_param -n llite.*.read_ahead_stats=0
9777         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9778
9779         #
9780         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9781         #
9782         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9783         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9784
9785         discard=0
9786         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9787                    get_named_value 'read.but.discarded'); do
9788                         discard=$(($discard + $s))
9789         done
9790         cleanup_101a
9791
9792         $LCTL get_param osc.*-osc*.rpc_stats
9793         $LCTL get_param llite.*.read_ahead_stats
9794
9795         # Discard is generally zero, but sometimes a few random reads line up
9796         # and trigger larger readahead, which is wasted & leads to discards.
9797         if [[ $(($discard)) -gt $nreads ]]; then
9798                 error "too many ($discard) discarded pages"
9799         fi
9800         rm -f $DIR/$tfile || true
9801 }
9802 run_test 101a "check read-ahead for random reads"
9803
9804 setup_test101bc() {
9805         test_mkdir $DIR/$tdir
9806         local ssize=$1
9807         local FILE_LENGTH=$2
9808         STRIPE_OFFSET=0
9809
9810         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9811
9812         local list=$(comma_list $(osts_nodes))
9813         set_osd_param $list '' read_cache_enable 0
9814         set_osd_param $list '' writethrough_cache_enable 0
9815
9816         trap cleanup_test101bc EXIT
9817         # prepare the read-ahead file
9818         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9819
9820         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9821                                 count=$FILE_SIZE_MB 2> /dev/null
9822
9823 }
9824
9825 cleanup_test101bc() {
9826         trap 0
9827         rm -rf $DIR/$tdir
9828         rm -f $DIR/$tfile
9829
9830         local list=$(comma_list $(osts_nodes))
9831         set_osd_param $list '' read_cache_enable 1
9832         set_osd_param $list '' writethrough_cache_enable 1
9833 }
9834
9835 calc_total() {
9836         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9837 }
9838
9839 ra_check_101() {
9840         local READ_SIZE=$1
9841         local STRIPE_SIZE=$2
9842         local FILE_LENGTH=$3
9843         local RA_INC=1048576
9844         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9845         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9846                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9847         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9848                   get_named_value 'read.but.discarded' | calc_total)
9849         if [[ $DISCARD -gt $discard_limit ]]; then
9850                 $LCTL get_param llite.*.read_ahead_stats
9851                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9852         else
9853                 echo "Read-ahead success for size ${READ_SIZE}"
9854         fi
9855 }
9856
9857 test_101b() {
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9860
9861         local STRIPE_SIZE=1048576
9862         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9863
9864         if [ $SLOW == "yes" ]; then
9865                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9866         else
9867                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9868         fi
9869
9870         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9871
9872         # prepare the read-ahead file
9873         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9874         cancel_lru_locks osc
9875         for BIDX in 2 4 8 16 32 64 128 256
9876         do
9877                 local BSIZE=$((BIDX*4096))
9878                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9879                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9880                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9881                 $LCTL set_param -n llite.*.read_ahead_stats=0
9882                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9883                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9884                 cancel_lru_locks osc
9885                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9886         done
9887         cleanup_test101bc
9888         true
9889 }
9890 run_test 101b "check stride-io mode read-ahead ================="
9891
9892 test_101c() {
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894
9895         local STRIPE_SIZE=1048576
9896         local FILE_LENGTH=$((STRIPE_SIZE*100))
9897         local nreads=10000
9898         local rsize=65536
9899         local osc_rpc_stats
9900
9901         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9902
9903         cancel_lru_locks osc
9904         $LCTL set_param osc.*.rpc_stats=0
9905         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9906         $LCTL get_param osc.*.rpc_stats
9907         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9908                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9909                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9910                 local size
9911
9912                 if [ $lines -le 20 ]; then
9913                         echo "continue debug"
9914                         continue
9915                 fi
9916                 for size in 1 2 4 8; do
9917                         local rpc=$(echo "$stats" |
9918                                     awk '($1 == "'$size':") {print $2; exit; }')
9919                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9920                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9921                 done
9922                 echo "$osc_rpc_stats check passed!"
9923         done
9924         cleanup_test101bc
9925         true
9926 }
9927 run_test 101c "check stripe_size aligned read-ahead"
9928
9929 test_101d() {
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931
9932         local file=$DIR/$tfile
9933         local sz_MB=${FILESIZE_101d:-80}
9934         local ra_MB=${READAHEAD_MB:-40}
9935
9936         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9937         [ $free_MB -lt $sz_MB ] &&
9938                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9939
9940         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9941         $LFS setstripe -c -1 $file || error "setstripe failed"
9942
9943         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9944         echo Cancel LRU locks on lustre client to flush the client cache
9945         cancel_lru_locks osc
9946
9947         echo Disable read-ahead
9948         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9949         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9950         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9951         $LCTL get_param -n llite.*.max_read_ahead_mb
9952
9953         echo "Reading the test file $file with read-ahead disabled"
9954         local sz_KB=$((sz_MB * 1024 / 4))
9955         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9956         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9957         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9958                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9959
9960         echo "Cancel LRU locks on lustre client to flush the client cache"
9961         cancel_lru_locks osc
9962         echo Enable read-ahead with ${ra_MB}MB
9963         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9964
9965         echo "Reading the test file $file with read-ahead enabled"
9966         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9967                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9968
9969         echo "read-ahead disabled time read $raOFF"
9970         echo "read-ahead enabled time read $raON"
9971
9972         rm -f $file
9973         wait_delete_completed
9974
9975         # use awk for this check instead of bash because it handles decimals
9976         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9977                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9978 }
9979 run_test 101d "file read with and without read-ahead enabled"
9980
9981 test_101e() {
9982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9983
9984         local file=$DIR/$tfile
9985         local size_KB=500  #KB
9986         local count=100
9987         local bsize=1024
9988
9989         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9990         local need_KB=$((count * size_KB))
9991         [[ $free_KB -le $need_KB ]] &&
9992                 skip_env "Need free space $need_KB, have $free_KB"
9993
9994         echo "Creating $count ${size_KB}K test files"
9995         for ((i = 0; i < $count; i++)); do
9996                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9997         done
9998
9999         echo "Cancel LRU locks on lustre client to flush the client cache"
10000         cancel_lru_locks $OSC
10001
10002         echo "Reset readahead stats"
10003         $LCTL set_param -n llite.*.read_ahead_stats=0
10004
10005         for ((i = 0; i < $count; i++)); do
10006                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10007         done
10008
10009         $LCTL get_param llite.*.max_cached_mb
10010         $LCTL get_param llite.*.read_ahead_stats
10011         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10012                      get_named_value 'misses' | calc_total)
10013
10014         for ((i = 0; i < $count; i++)); do
10015                 rm -rf $file.$i 2>/dev/null
10016         done
10017
10018         #10000 means 20% reads are missing in readahead
10019         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10020 }
10021 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10022
10023 test_101f() {
10024         which iozone || skip_env "no iozone installed"
10025
10026         local old_debug=$($LCTL get_param debug)
10027         old_debug=${old_debug#*=}
10028         $LCTL set_param debug="reada mmap"
10029
10030         # create a test file
10031         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10032
10033         echo Cancel LRU locks on lustre client to flush the client cache
10034         cancel_lru_locks osc
10035
10036         echo Reset readahead stats
10037         $LCTL set_param -n llite.*.read_ahead_stats=0
10038
10039         echo mmap read the file with small block size
10040         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10041                 > /dev/null 2>&1
10042
10043         echo checking missing pages
10044         $LCTL get_param llite.*.read_ahead_stats
10045         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10046                         get_named_value 'misses' | calc_total)
10047
10048         $LCTL set_param debug="$old_debug"
10049         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10050         rm -f $DIR/$tfile
10051 }
10052 run_test 101f "check mmap read performance"
10053
10054 test_101g_brw_size_test() {
10055         local mb=$1
10056         local pages=$((mb * 1048576 / PAGE_SIZE))
10057         local file=$DIR/$tfile
10058
10059         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10060                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10061         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10062                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10063                         return 2
10064         done
10065
10066         stack_trap "rm -f $file" EXIT
10067         $LCTL set_param -n osc.*.rpc_stats=0
10068
10069         # 10 RPCs should be enough for the test
10070         local count=10
10071         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10072                 { error "dd write ${mb} MB blocks failed"; return 3; }
10073         cancel_lru_locks osc
10074         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10075                 { error "dd write ${mb} MB blocks failed"; return 4; }
10076
10077         # calculate number of full-sized read and write RPCs
10078         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10079                 sed -n '/pages per rpc/,/^$/p' |
10080                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10081                 END { print reads,writes }'))
10082         # allow one extra full-sized read RPC for async readahead
10083         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10084                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10085         [[ ${rpcs[1]} == $count ]] ||
10086                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10087 }
10088
10089 test_101g() {
10090         remote_ost_nodsh && skip "remote OST with nodsh"
10091
10092         local rpcs
10093         local osts=$(get_facets OST)
10094         local list=$(comma_list $(osts_nodes))
10095         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10096         local brw_size="obdfilter.*.brw_size"
10097
10098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10099
10100         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10101
10102         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10103                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10104                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10105            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10106                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10107                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10108
10109                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10110                         suffix="M"
10111
10112                 if [[ $orig_mb -lt 16 ]]; then
10113                         save_lustre_params $osts "$brw_size" > $p
10114                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10115                                 error "set 16MB RPC size failed"
10116
10117                         echo "remount client to enable new RPC size"
10118                         remount_client $MOUNT || error "remount_client failed"
10119                 fi
10120
10121                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10122                 # should be able to set brw_size=12, but no rpc_stats for that
10123                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10124         fi
10125
10126         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10127
10128         if [[ $orig_mb -lt 16 ]]; then
10129                 restore_lustre_params < $p
10130                 remount_client $MOUNT || error "remount_client restore failed"
10131         fi
10132
10133         rm -f $p $DIR/$tfile
10134 }
10135 run_test 101g "Big bulk(4/16 MiB) readahead"
10136
10137 test_101h() {
10138         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10139
10140         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10141                 error "dd 70M file failed"
10142         echo Cancel LRU locks on lustre client to flush the client cache
10143         cancel_lru_locks osc
10144
10145         echo "Reset readahead stats"
10146         $LCTL set_param -n llite.*.read_ahead_stats 0
10147
10148         echo "Read 10M of data but cross 64M bundary"
10149         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10150         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10151                      get_named_value 'misses' | calc_total)
10152         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10153         rm -f $p $DIR/$tfile
10154 }
10155 run_test 101h "Readahead should cover current read window"
10156
10157 test_101i() {
10158         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10159                 error "dd 10M file failed"
10160
10161         local max_per_file_mb=$($LCTL get_param -n \
10162                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10163         cancel_lru_locks osc
10164         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10165         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10166                 error "set max_read_ahead_per_file_mb to 1 failed"
10167
10168         echo "Reset readahead stats"
10169         $LCTL set_param llite.*.read_ahead_stats=0
10170
10171         dd if=$DIR/$tfile of=/dev/null bs=2M
10172
10173         $LCTL get_param llite.*.read_ahead_stats
10174         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10175                      awk '/misses/ { print $2 }')
10176         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10177         rm -f $DIR/$tfile
10178 }
10179 run_test 101i "allow current readahead to exceed reservation"
10180
10181 test_101j() {
10182         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10183                 error "setstripe $DIR/$tfile failed"
10184         local file_size=$((1048576 * 16))
10185         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10186         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10187
10188         echo Disable read-ahead
10189         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10190
10191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10192         for blk in $PAGE_SIZE 1048576 $file_size; do
10193                 cancel_lru_locks osc
10194                 echo "Reset readahead stats"
10195                 $LCTL set_param -n llite.*.read_ahead_stats=0
10196                 local count=$(($file_size / $blk))
10197                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10198                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10199                              get_named_value 'failed.to.fast.read' | calc_total)
10200                 $LCTL get_param -n llite.*.read_ahead_stats
10201                 [ $miss -eq $count ] || error "expected $count got $miss"
10202         done
10203
10204         rm -f $p $DIR/$tfile
10205 }
10206 run_test 101j "A complete read block should be submitted when no RA"
10207
10208 setup_test102() {
10209         test_mkdir $DIR/$tdir
10210         chown $RUNAS_ID $DIR/$tdir
10211         STRIPE_SIZE=65536
10212         STRIPE_OFFSET=1
10213         STRIPE_COUNT=$OSTCOUNT
10214         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10215
10216         trap cleanup_test102 EXIT
10217         cd $DIR
10218         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10219         cd $DIR/$tdir
10220         for num in 1 2 3 4; do
10221                 for count in $(seq 1 $STRIPE_COUNT); do
10222                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10223                                 local size=`expr $STRIPE_SIZE \* $num`
10224                                 local file=file"$num-$idx-$count"
10225                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10226                         done
10227                 done
10228         done
10229
10230         cd $DIR
10231         $1 tar cf $TMP/f102.tar $tdir --xattrs
10232 }
10233
10234 cleanup_test102() {
10235         trap 0
10236         rm -f $TMP/f102.tar
10237         rm -rf $DIR/d0.sanity/d102
10238 }
10239
10240 test_102a() {
10241         [ "$UID" != 0 ] && skip "must run as root"
10242         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10243                 skip_env "must have user_xattr"
10244
10245         [ -z "$(which setfattr 2>/dev/null)" ] &&
10246                 skip_env "could not find setfattr"
10247
10248         local testfile=$DIR/$tfile
10249
10250         touch $testfile
10251         echo "set/get xattr..."
10252         setfattr -n trusted.name1 -v value1 $testfile ||
10253                 error "setfattr -n trusted.name1=value1 $testfile failed"
10254         getfattr -n trusted.name1 $testfile 2> /dev/null |
10255           grep "trusted.name1=.value1" ||
10256                 error "$testfile missing trusted.name1=value1"
10257
10258         setfattr -n user.author1 -v author1 $testfile ||
10259                 error "setfattr -n user.author1=author1 $testfile failed"
10260         getfattr -n user.author1 $testfile 2> /dev/null |
10261           grep "user.author1=.author1" ||
10262                 error "$testfile missing trusted.author1=author1"
10263
10264         echo "listxattr..."
10265         setfattr -n trusted.name2 -v value2 $testfile ||
10266                 error "$testfile unable to set trusted.name2"
10267         setfattr -n trusted.name3 -v value3 $testfile ||
10268                 error "$testfile unable to set trusted.name3"
10269         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10270             grep "trusted.name" | wc -l) -eq 3 ] ||
10271                 error "$testfile missing 3 trusted.name xattrs"
10272
10273         setfattr -n user.author2 -v author2 $testfile ||
10274                 error "$testfile unable to set user.author2"
10275         setfattr -n user.author3 -v author3 $testfile ||
10276                 error "$testfile unable to set user.author3"
10277         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10278             grep "user.author" | wc -l) -eq 3 ] ||
10279                 error "$testfile missing 3 user.author xattrs"
10280
10281         echo "remove xattr..."
10282         setfattr -x trusted.name1 $testfile ||
10283                 error "$testfile error deleting trusted.name1"
10284         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10285                 error "$testfile did not delete trusted.name1 xattr"
10286
10287         setfattr -x user.author1 $testfile ||
10288                 error "$testfile error deleting user.author1"
10289         echo "set lustre special xattr ..."
10290         $LFS setstripe -c1 $testfile
10291         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10292                 awk -F "=" '/trusted.lov/ { print $2 }' )
10293         setfattr -n "trusted.lov" -v $lovea $testfile ||
10294                 error "$testfile doesn't ignore setting trusted.lov again"
10295         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10296                 error "$testfile allow setting invalid trusted.lov"
10297         rm -f $testfile
10298 }
10299 run_test 102a "user xattr test =================================="
10300
10301 check_102b_layout() {
10302         local layout="$*"
10303         local testfile=$DIR/$tfile
10304
10305         echo "test layout '$layout'"
10306         $LFS setstripe $layout $testfile || error "setstripe failed"
10307         $LFS getstripe -y $testfile
10308
10309         echo "get/set/list trusted.lov xattr ..." # b=10930
10310         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10311         [[ "$value" =~ "trusted.lov" ]] ||
10312                 error "can't get trusted.lov from $testfile"
10313         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10314                 error "getstripe failed"
10315
10316         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10317
10318         value=$(cut -d= -f2 <<<$value)
10319         # LU-13168: truncated xattr should fail if short lov_user_md header
10320         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10321                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10322         for len in $lens; do
10323                 echo "setfattr $len $testfile.2"
10324                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10325                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10326         done
10327         local stripe_size=$($LFS getstripe -S $testfile.2)
10328         local stripe_count=$($LFS getstripe -c $testfile.2)
10329         [[ $stripe_size -eq 65536 ]] ||
10330                 error "stripe size $stripe_size != 65536"
10331         [[ $stripe_count -eq $stripe_count_orig ]] ||
10332                 error "stripe count $stripe_count != $stripe_count_orig"
10333         rm $testfile $testfile.2
10334 }
10335
10336 test_102b() {
10337         [ -z "$(which setfattr 2>/dev/null)" ] &&
10338                 skip_env "could not find setfattr"
10339         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10340
10341         # check plain layout
10342         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10343
10344         # and also check composite layout
10345         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10346
10347 }
10348 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10349
10350 test_102c() {
10351         [ -z "$(which setfattr 2>/dev/null)" ] &&
10352                 skip_env "could not find setfattr"
10353         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10354
10355         # b10930: get/set/list lustre.lov xattr
10356         echo "get/set/list lustre.lov xattr ..."
10357         test_mkdir $DIR/$tdir
10358         chown $RUNAS_ID $DIR/$tdir
10359         local testfile=$DIR/$tdir/$tfile
10360         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10361                 error "setstripe failed"
10362         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10363                 error "getstripe failed"
10364         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10365         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10366
10367         local testfile2=${testfile}2
10368         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10369                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10370
10371         $RUNAS $MCREATE $testfile2
10372         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10373         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10374         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10375         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10376         [ $stripe_count -eq $STRIPECOUNT ] ||
10377                 error "stripe count $stripe_count != $STRIPECOUNT"
10378 }
10379 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10380
10381 compare_stripe_info1() {
10382         local stripe_index_all_zero=true
10383
10384         for num in 1 2 3 4; do
10385                 for count in $(seq 1 $STRIPE_COUNT); do
10386                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10387                                 local size=$((STRIPE_SIZE * num))
10388                                 local file=file"$num-$offset-$count"
10389                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10390                                 [[ $stripe_size -ne $size ]] &&
10391                                     error "$file: size $stripe_size != $size"
10392                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10393                                 # allow fewer stripes to be created, ORI-601
10394                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10395                                     error "$file: count $stripe_count != $count"
10396                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10397                                 [[ $stripe_index -ne 0 ]] &&
10398                                         stripe_index_all_zero=false
10399                         done
10400                 done
10401         done
10402         $stripe_index_all_zero &&
10403                 error "all files are being extracted starting from OST index 0"
10404         return 0
10405 }
10406
10407 have_xattrs_include() {
10408         tar --help | grep -q xattrs-include &&
10409                 echo --xattrs-include="lustre.*"
10410 }
10411
10412 test_102d() {
10413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10415
10416         XINC=$(have_xattrs_include)
10417         setup_test102
10418         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10419         cd $DIR/$tdir/$tdir
10420         compare_stripe_info1
10421 }
10422 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10423
10424 test_102f() {
10425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10426         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10427
10428         XINC=$(have_xattrs_include)
10429         setup_test102
10430         test_mkdir $DIR/$tdir.restore
10431         cd $DIR
10432         tar cf - --xattrs $tdir | tar xf - \
10433                 -C $DIR/$tdir.restore --xattrs $XINC
10434         cd $DIR/$tdir.restore/$tdir
10435         compare_stripe_info1
10436 }
10437 run_test 102f "tar copy files, not keep osts"
10438
10439 grow_xattr() {
10440         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10441                 skip "must have user_xattr"
10442         [ -z "$(which setfattr 2>/dev/null)" ] &&
10443                 skip_env "could not find setfattr"
10444         [ -z "$(which getfattr 2>/dev/null)" ] &&
10445                 skip_env "could not find getfattr"
10446
10447         local xsize=${1:-1024}  # in bytes
10448         local file=$DIR/$tfile
10449         local value="$(generate_string $xsize)"
10450         local xbig=trusted.big
10451         local toobig=$2
10452
10453         touch $file
10454         log "save $xbig on $file"
10455         if [ -z "$toobig" ]
10456         then
10457                 setfattr -n $xbig -v $value $file ||
10458                         error "saving $xbig on $file failed"
10459         else
10460                 setfattr -n $xbig -v $value $file &&
10461                         error "saving $xbig on $file succeeded"
10462                 return 0
10463         fi
10464
10465         local orig=$(get_xattr_value $xbig $file)
10466         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10467
10468         local xsml=trusted.sml
10469         log "save $xsml on $file"
10470         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10471
10472         local new=$(get_xattr_value $xbig $file)
10473         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10474
10475         log "grow $xsml on $file"
10476         setfattr -n $xsml -v "$value" $file ||
10477                 error "growing $xsml on $file failed"
10478
10479         new=$(get_xattr_value $xbig $file)
10480         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10481         log "$xbig still valid after growing $xsml"
10482
10483         rm -f $file
10484 }
10485
10486 test_102h() { # bug 15777
10487         grow_xattr 1024
10488 }
10489 run_test 102h "grow xattr from inside inode to external block"
10490
10491 test_102ha() {
10492         large_xattr_enabled || skip_env "ea_inode feature disabled"
10493
10494         echo "setting xattr of max xattr size: $(max_xattr_size)"
10495         grow_xattr $(max_xattr_size)
10496
10497         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10498         echo "This should fail:"
10499         grow_xattr $(($(max_xattr_size) + 10)) 1
10500 }
10501 run_test 102ha "grow xattr from inside inode to external inode"
10502
10503 test_102i() { # bug 17038
10504         [ -z "$(which getfattr 2>/dev/null)" ] &&
10505                 skip "could not find getfattr"
10506
10507         touch $DIR/$tfile
10508         ln -s $DIR/$tfile $DIR/${tfile}link
10509         getfattr -n trusted.lov $DIR/$tfile ||
10510                 error "lgetxattr on $DIR/$tfile failed"
10511         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10512                 grep -i "no such attr" ||
10513                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10514         rm -f $DIR/$tfile $DIR/${tfile}link
10515 }
10516 run_test 102i "lgetxattr test on symbolic link ============"
10517
10518 test_102j() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10521
10522         XINC=$(have_xattrs_include)
10523         setup_test102 "$RUNAS"
10524         chown $RUNAS_ID $DIR/$tdir
10525         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10526         cd $DIR/$tdir/$tdir
10527         compare_stripe_info1 "$RUNAS"
10528 }
10529 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10530
10531 test_102k() {
10532         [ -z "$(which setfattr 2>/dev/null)" ] &&
10533                 skip "could not find setfattr"
10534
10535         touch $DIR/$tfile
10536         # b22187 just check that does not crash for regular file.
10537         setfattr -n trusted.lov $DIR/$tfile
10538         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10539         local test_kdir=$DIR/$tdir
10540         test_mkdir $test_kdir
10541         local default_size=$($LFS getstripe -S $test_kdir)
10542         local default_count=$($LFS getstripe -c $test_kdir)
10543         local default_offset=$($LFS getstripe -i $test_kdir)
10544         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10545                 error 'dir setstripe failed'
10546         setfattr -n trusted.lov $test_kdir
10547         local stripe_size=$($LFS getstripe -S $test_kdir)
10548         local stripe_count=$($LFS getstripe -c $test_kdir)
10549         local stripe_offset=$($LFS getstripe -i $test_kdir)
10550         [ $stripe_size -eq $default_size ] ||
10551                 error "stripe size $stripe_size != $default_size"
10552         [ $stripe_count -eq $default_count ] ||
10553                 error "stripe count $stripe_count != $default_count"
10554         [ $stripe_offset -eq $default_offset ] ||
10555                 error "stripe offset $stripe_offset != $default_offset"
10556         rm -rf $DIR/$tfile $test_kdir
10557 }
10558 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10559
10560 test_102l() {
10561         [ -z "$(which getfattr 2>/dev/null)" ] &&
10562                 skip "could not find getfattr"
10563
10564         # LU-532 trusted. xattr is invisible to non-root
10565         local testfile=$DIR/$tfile
10566
10567         touch $testfile
10568
10569         echo "listxattr as user..."
10570         chown $RUNAS_ID $testfile
10571         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10572             grep -q "trusted" &&
10573                 error "$testfile trusted xattrs are user visible"
10574
10575         return 0;
10576 }
10577 run_test 102l "listxattr size test =================================="
10578
10579 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10580         local path=$DIR/$tfile
10581         touch $path
10582
10583         listxattr_size_check $path || error "listattr_size_check $path failed"
10584 }
10585 run_test 102m "Ensure listxattr fails on small bufffer ========"
10586
10587 cleanup_test102
10588
10589 getxattr() { # getxattr path name
10590         # Return the base64 encoding of the value of xattr name on path.
10591         local path=$1
10592         local name=$2
10593
10594         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10595         # file: $path
10596         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10597         #
10598         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10599
10600         getfattr --absolute-names --encoding=base64 --name=$name $path |
10601                 awk -F= -v name=$name '$1 == name {
10602                         print substr($0, index($0, "=") + 1);
10603         }'
10604 }
10605
10606 test_102n() { # LU-4101 mdt: protect internal xattrs
10607         [ -z "$(which setfattr 2>/dev/null)" ] &&
10608                 skip "could not find setfattr"
10609         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10610         then
10611                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10612         fi
10613
10614         local file0=$DIR/$tfile.0
10615         local file1=$DIR/$tfile.1
10616         local xattr0=$TMP/$tfile.0
10617         local xattr1=$TMP/$tfile.1
10618         local namelist="lov lma lmv link fid version som hsm"
10619         local name
10620         local value
10621
10622         rm -rf $file0 $file1 $xattr0 $xattr1
10623         touch $file0 $file1
10624
10625         # Get 'before' xattrs of $file1.
10626         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10627
10628         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10629                 namelist+=" lfsck_namespace"
10630         for name in $namelist; do
10631                 # Try to copy xattr from $file0 to $file1.
10632                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10633
10634                 setfattr --name=trusted.$name --value="$value" $file1 ||
10635                         error "setxattr 'trusted.$name' failed"
10636
10637                 # Try to set a garbage xattr.
10638                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10639
10640                 if [[ x$name == "xlov" ]]; then
10641                         setfattr --name=trusted.lov --value="$value" $file1 &&
10642                         error "setxattr invalid 'trusted.lov' success"
10643                 else
10644                         setfattr --name=trusted.$name --value="$value" $file1 ||
10645                                 error "setxattr invalid 'trusted.$name' failed"
10646                 fi
10647
10648                 # Try to remove the xattr from $file1. We don't care if this
10649                 # appears to succeed or fail, we just don't want there to be
10650                 # any changes or crashes.
10651                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10652         done
10653
10654         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10655         then
10656                 name="lfsck_ns"
10657                 # Try to copy xattr from $file0 to $file1.
10658                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10659
10660                 setfattr --name=trusted.$name --value="$value" $file1 ||
10661                         error "setxattr 'trusted.$name' failed"
10662
10663                 # Try to set a garbage xattr.
10664                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10665
10666                 setfattr --name=trusted.$name --value="$value" $file1 ||
10667                         error "setxattr 'trusted.$name' failed"
10668
10669                 # Try to remove the xattr from $file1. We don't care if this
10670                 # appears to succeed or fail, we just don't want there to be
10671                 # any changes or crashes.
10672                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10673         fi
10674
10675         # Get 'after' xattrs of file1.
10676         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10677
10678         if ! diff $xattr0 $xattr1; then
10679                 error "before and after xattrs of '$file1' differ"
10680         fi
10681
10682         rm -rf $file0 $file1 $xattr0 $xattr1
10683
10684         return 0
10685 }
10686 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10687
10688 test_102p() { # LU-4703 setxattr did not check ownership
10689         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10690                 skip "MDS needs to be at least 2.5.56"
10691
10692         local testfile=$DIR/$tfile
10693
10694         touch $testfile
10695
10696         echo "setfacl as user..."
10697         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10698         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10699
10700         echo "setfattr as user..."
10701         setfacl -m "u:$RUNAS_ID:---" $testfile
10702         $RUNAS setfattr -x system.posix_acl_access $testfile
10703         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10704 }
10705 run_test 102p "check setxattr(2) correctly fails without permission"
10706
10707 test_102q() {
10708         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10709                 skip "MDS needs to be at least 2.6.92"
10710
10711         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10712 }
10713 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10714
10715 test_102r() {
10716         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10717                 skip "MDS needs to be at least 2.6.93"
10718
10719         touch $DIR/$tfile || error "touch"
10720         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10721         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10722         rm $DIR/$tfile || error "rm"
10723
10724         #normal directory
10725         mkdir -p $DIR/$tdir || error "mkdir"
10726         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10727         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10728         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10729                 error "$testfile error deleting user.author1"
10730         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10731                 grep "user.$(basename $tdir)" &&
10732                 error "$tdir did not delete user.$(basename $tdir)"
10733         rmdir $DIR/$tdir || error "rmdir"
10734
10735         #striped directory
10736         test_mkdir $DIR/$tdir
10737         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10738         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10739         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10740                 error "$testfile error deleting user.author1"
10741         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10742                 grep "user.$(basename $tdir)" &&
10743                 error "$tdir did not delete user.$(basename $tdir)"
10744         rmdir $DIR/$tdir || error "rm striped dir"
10745 }
10746 run_test 102r "set EAs with empty values"
10747
10748 test_102s() {
10749         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10750                 skip "MDS needs to be at least 2.11.52"
10751
10752         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10753
10754         save_lustre_params client "llite.*.xattr_cache" > $save
10755
10756         for cache in 0 1; do
10757                 lctl set_param llite.*.xattr_cache=$cache
10758
10759                 rm -f $DIR/$tfile
10760                 touch $DIR/$tfile || error "touch"
10761                 for prefix in lustre security system trusted user; do
10762                         # Note getxattr() may fail with 'Operation not
10763                         # supported' or 'No such attribute' depending
10764                         # on prefix and cache.
10765                         getfattr -n $prefix.n102s $DIR/$tfile &&
10766                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10767                 done
10768         done
10769
10770         restore_lustre_params < $save
10771 }
10772 run_test 102s "getting nonexistent xattrs should fail"
10773
10774 test_102t() {
10775         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10776                 skip "MDS needs to be at least 2.11.52"
10777
10778         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10779
10780         save_lustre_params client "llite.*.xattr_cache" > $save
10781
10782         for cache in 0 1; do
10783                 lctl set_param llite.*.xattr_cache=$cache
10784
10785                 for buf_size in 0 256; do
10786                         rm -f $DIR/$tfile
10787                         touch $DIR/$tfile || error "touch"
10788                         setfattr -n user.multiop $DIR/$tfile
10789                         $MULTIOP $DIR/$tfile oa$buf_size ||
10790                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10791                 done
10792         done
10793
10794         restore_lustre_params < $save
10795 }
10796 run_test 102t "zero length xattr values handled correctly"
10797
10798 run_acl_subtest()
10799 {
10800     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10801     return $?
10802 }
10803
10804 test_103a() {
10805         [ "$UID" != 0 ] && skip "must run as root"
10806         $GSS && skip_env "could not run under gss"
10807         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10808                 skip_env "must have acl enabled"
10809         [ -z "$(which setfacl 2>/dev/null)" ] &&
10810                 skip_env "could not find setfacl"
10811         remote_mds_nodsh && skip "remote MDS with nodsh"
10812
10813         gpasswd -a daemon bin                           # LU-5641
10814         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10815
10816         declare -a identity_old
10817
10818         for num in $(seq $MDSCOUNT); do
10819                 switch_identity $num true || identity_old[$num]=$?
10820         done
10821
10822         SAVE_UMASK=$(umask)
10823         umask 0022
10824         mkdir -p $DIR/$tdir
10825         cd $DIR/$tdir
10826
10827         echo "performing cp ..."
10828         run_acl_subtest cp || error "run_acl_subtest cp failed"
10829         echo "performing getfacl-noacl..."
10830         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10831         echo "performing misc..."
10832         run_acl_subtest misc || error  "misc test failed"
10833         echo "performing permissions..."
10834         run_acl_subtest permissions || error "permissions failed"
10835         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10836         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10837                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10838                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10839         then
10840                 echo "performing permissions xattr..."
10841                 run_acl_subtest permissions_xattr ||
10842                         error "permissions_xattr failed"
10843         fi
10844         echo "performing setfacl..."
10845         run_acl_subtest setfacl || error  "setfacl test failed"
10846
10847         # inheritance test got from HP
10848         echo "performing inheritance..."
10849         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10850         chmod +x make-tree || error "chmod +x failed"
10851         run_acl_subtest inheritance || error "inheritance test failed"
10852         rm -f make-tree
10853
10854         echo "LU-974 ignore umask when acl is enabled..."
10855         run_acl_subtest 974 || error "LU-974 umask test failed"
10856         if [ $MDSCOUNT -ge 2 ]; then
10857                 run_acl_subtest 974_remote ||
10858                         error "LU-974 umask test failed under remote dir"
10859         fi
10860
10861         echo "LU-2561 newly created file is same size as directory..."
10862         if [ "$mds1_FSTYPE" != "zfs" ]; then
10863                 run_acl_subtest 2561 || error "LU-2561 test failed"
10864         else
10865                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10866         fi
10867
10868         run_acl_subtest 4924 || error "LU-4924 test failed"
10869
10870         cd $SAVE_PWD
10871         umask $SAVE_UMASK
10872
10873         for num in $(seq $MDSCOUNT); do
10874                 if [ "${identity_old[$num]}" = 1 ]; then
10875                         switch_identity $num false || identity_old[$num]=$?
10876                 fi
10877         done
10878 }
10879 run_test 103a "acl test"
10880
10881 test_103b() {
10882         declare -a pids
10883         local U
10884
10885         for U in {0..511}; do
10886                 {
10887                 local O=$(printf "%04o" $U)
10888
10889                 umask $(printf "%04o" $((511 ^ $O)))
10890                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10891                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10892
10893                 (( $S == ($O & 0666) )) ||
10894                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10895
10896                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10897                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10898                 (( $S == ($O & 0666) )) ||
10899                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10900
10901                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10902                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10903                 (( $S == ($O & 0666) )) ||
10904                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10905                 rm -f $DIR/$tfile.[smp]$0
10906                 } &
10907                 local pid=$!
10908
10909                 # limit the concurrently running threads to 64. LU-11878
10910                 local idx=$((U % 64))
10911                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10912                 pids[idx]=$pid
10913         done
10914         wait
10915 }
10916 run_test 103b "umask lfs setstripe"
10917
10918 test_103c() {
10919         mkdir -p $DIR/$tdir
10920         cp -rp $DIR/$tdir $DIR/$tdir.bak
10921
10922         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10923                 error "$DIR/$tdir shouldn't contain default ACL"
10924         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10925                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10926         true
10927 }
10928 run_test 103c "'cp -rp' won't set empty acl"
10929
10930 test_103e() {
10931         local numacl
10932         local fileacl
10933         local saved_debug=$($LCTL get_param -n debug)
10934
10935         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10936                 skip "MDS needs to be at least 2.14.0"
10937
10938         large_xattr_enabled || skip_env "ea_inode feature disabled"
10939
10940         mkdir -p $DIR/$tdir
10941         # add big LOV EA to cause reply buffer overflow earlier
10942         $LFS setstripe -C 1000 $DIR/$tdir
10943         lctl set_param mdc.*-mdc*.stats=clear
10944
10945         $LCTL set_param debug=0
10946         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10947         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10948
10949         # add a large number of default ACLs (expect 8000+ for 2.13+)
10950         for U in {2..7000}; do
10951                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10952                         error "Able to add just $U default ACLs"
10953         done
10954         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10955         echo "$numacl default ACLs created"
10956
10957         stat $DIR/$tdir || error "Cannot stat directory"
10958         # check file creation
10959         touch $DIR/$tdir/$tfile ||
10960                 error "failed to create $tfile with $numacl default ACLs"
10961         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10962         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10963         echo "$fileacl ACLs were inherited"
10964         (( $fileacl == $numacl )) ||
10965                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10966         # check that new ACLs creation adds new ACLs to inherited ACLs
10967         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10968                 error "Cannot set new ACL"
10969         numacl=$((numacl + 1))
10970         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10971         (( $fileacl == $numacl )) ||
10972                 error "failed to add new ACL: $fileacl != $numacl as expected"
10973         # adds more ACLs to a file to reach their maximum at 8000+
10974         numacl=0
10975         for U in {20000..25000}; do
10976                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10977                 numacl=$((numacl + 1))
10978         done
10979         echo "Added $numacl more ACLs to the file"
10980         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10981         echo "Total $fileacl ACLs in file"
10982         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10983         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10984         rmdir $DIR/$tdir || error "Cannot remove directory"
10985 }
10986 run_test 103e "inheritance of big amount of default ACLs"
10987
10988 test_103f() {
10989         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
10990                 skip "MDS needs to be at least 2.14.51"
10991
10992         large_xattr_enabled || skip_env "ea_inode feature disabled"
10993
10994         # enable changelog to consume more internal MDD buffers
10995         changelog_register
10996
10997         mkdir -p $DIR/$tdir
10998         # add big LOV EA
10999         $LFS setstripe -C 1000 $DIR/$tdir
11000         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11001         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11002         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11003         rmdir $DIR/$tdir || error "Cannot remove directory"
11004 }
11005 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11006
11007 test_104a() {
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009
11010         touch $DIR/$tfile
11011         lfs df || error "lfs df failed"
11012         lfs df -ih || error "lfs df -ih failed"
11013         lfs df -h $DIR || error "lfs df -h $DIR failed"
11014         lfs df -i $DIR || error "lfs df -i $DIR failed"
11015         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11016         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11017
11018         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11019         lctl --device %$OSC deactivate
11020         lfs df || error "lfs df with deactivated OSC failed"
11021         lctl --device %$OSC activate
11022         # wait the osc back to normal
11023         wait_osc_import_ready client ost
11024
11025         lfs df || error "lfs df with reactivated OSC failed"
11026         rm -f $DIR/$tfile
11027 }
11028 run_test 104a "lfs df [-ih] [path] test ========================="
11029
11030 test_104b() {
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032         [ $RUNAS_ID -eq $UID ] &&
11033                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11034
11035         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11036                         grep "Permission denied" | wc -l)))
11037         if [ $denied_cnt -ne 0 ]; then
11038                 error "lfs check servers test failed"
11039         fi
11040 }
11041 run_test 104b "$RUNAS lfs check servers test ===================="
11042
11043 #
11044 # Verify $1 is within range of $2.
11045 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11046 # $1 is <= 2% of $2. Else Fail.
11047 #
11048 value_in_range() {
11049         # Strip all units (M, G, T)
11050         actual=$(echo $1 | tr -d A-Z)
11051         expect=$(echo $2 | tr -d A-Z)
11052
11053         expect_lo=$(($expect * 98 / 100)) # 2% below
11054         expect_hi=$(($expect * 102 / 100)) # 2% above
11055
11056         # permit 2% drift above and below
11057         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11058 }
11059
11060 test_104c() {
11061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11062         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11063
11064         local ost_param="osd-zfs.$FSNAME-OST0000."
11065         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11066         local ofacets=$(get_facets OST)
11067         local mfacets=$(get_facets MDS)
11068         local saved_ost_blocks=
11069         local saved_mdt_blocks=
11070
11071         echo "Before recordsize change"
11072         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11073         df=($(df -h | grep "/mnt/lustre"$))
11074
11075         # For checking.
11076         echo "lfs output : ${lfs_df[*]}"
11077         echo "df  output : ${df[*]}"
11078
11079         for facet in ${ofacets//,/ }; do
11080                 if [ -z $saved_ost_blocks ]; then
11081                         saved_ost_blocks=$(do_facet $facet \
11082                                 lctl get_param -n $ost_param.blocksize)
11083                         echo "OST Blocksize: $saved_ost_blocks"
11084                 fi
11085                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11086                 do_facet $facet zfs set recordsize=32768 $ost
11087         done
11088
11089         # BS too small. Sufficient for functional testing.
11090         for facet in ${mfacets//,/ }; do
11091                 if [ -z $saved_mdt_blocks ]; then
11092                         saved_mdt_blocks=$(do_facet $facet \
11093                                 lctl get_param -n $mdt_param.blocksize)
11094                         echo "MDT Blocksize: $saved_mdt_blocks"
11095                 fi
11096                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11097                 do_facet $facet zfs set recordsize=32768 $mdt
11098         done
11099
11100         # Give new values chance to reflect change
11101         sleep 2
11102
11103         echo "After recordsize change"
11104         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11105         df_after=($(df -h | grep "/mnt/lustre"$))
11106
11107         # For checking.
11108         echo "lfs output : ${lfs_df_after[*]}"
11109         echo "df  output : ${df_after[*]}"
11110
11111         # Verify lfs df
11112         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11113                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11114         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11115                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11116         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11117                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11118
11119         # Verify df
11120         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11121                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11122         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11123                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11124         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11125                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11126
11127         # Restore MDT recordize back to original
11128         for facet in ${mfacets//,/ }; do
11129                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11130                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11131         done
11132
11133         # Restore OST recordize back to original
11134         for facet in ${ofacets//,/ }; do
11135                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11136                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11137         done
11138
11139         return 0
11140 }
11141 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11142
11143 test_105a() {
11144         # doesn't work on 2.4 kernels
11145         touch $DIR/$tfile
11146         if $(flock_is_enabled); then
11147                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11148         else
11149                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11150         fi
11151         rm -f $DIR/$tfile
11152 }
11153 run_test 105a "flock when mounted without -o flock test ========"
11154
11155 test_105b() {
11156         touch $DIR/$tfile
11157         if $(flock_is_enabled); then
11158                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11159         else
11160                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11161         fi
11162         rm -f $DIR/$tfile
11163 }
11164 run_test 105b "fcntl when mounted without -o flock test ========"
11165
11166 test_105c() {
11167         touch $DIR/$tfile
11168         if $(flock_is_enabled); then
11169                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11170         else
11171                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11172         fi
11173         rm -f $DIR/$tfile
11174 }
11175 run_test 105c "lockf when mounted without -o flock test"
11176
11177 test_105d() { # bug 15924
11178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11179
11180         test_mkdir $DIR/$tdir
11181         flock_is_enabled || skip_env "mount w/o flock enabled"
11182         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11183         $LCTL set_param fail_loc=0x80000315
11184         flocks_test 2 $DIR/$tdir
11185 }
11186 run_test 105d "flock race (should not freeze) ========"
11187
11188 test_105e() { # bug 22660 && 22040
11189         flock_is_enabled || skip_env "mount w/o flock enabled"
11190
11191         touch $DIR/$tfile
11192         flocks_test 3 $DIR/$tfile
11193 }
11194 run_test 105e "Two conflicting flocks from same process"
11195
11196 test_106() { #bug 10921
11197         test_mkdir $DIR/$tdir
11198         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11199         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11200 }
11201 run_test 106 "attempt exec of dir followed by chown of that dir"
11202
11203 test_107() {
11204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11205
11206         CDIR=`pwd`
11207         local file=core
11208
11209         cd $DIR
11210         rm -f $file
11211
11212         local save_pattern=$(sysctl -n kernel.core_pattern)
11213         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11214         sysctl -w kernel.core_pattern=$file
11215         sysctl -w kernel.core_uses_pid=0
11216
11217         ulimit -c unlimited
11218         sleep 60 &
11219         SLEEPPID=$!
11220
11221         sleep 1
11222
11223         kill -s 11 $SLEEPPID
11224         wait $SLEEPPID
11225         if [ -e $file ]; then
11226                 size=`stat -c%s $file`
11227                 [ $size -eq 0 ] && error "Fail to create core file $file"
11228         else
11229                 error "Fail to create core file $file"
11230         fi
11231         rm -f $file
11232         sysctl -w kernel.core_pattern=$save_pattern
11233         sysctl -w kernel.core_uses_pid=$save_uses_pid
11234         cd $CDIR
11235 }
11236 run_test 107 "Coredump on SIG"
11237
11238 test_110() {
11239         test_mkdir $DIR/$tdir
11240         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11241         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11242                 error "mkdir with 256 char should fail, but did not"
11243         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11244                 error "create with 255 char failed"
11245         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11246                 error "create with 256 char should fail, but did not"
11247
11248         ls -l $DIR/$tdir
11249         rm -rf $DIR/$tdir
11250 }
11251 run_test 110 "filename length checking"
11252
11253 #
11254 # Purpose: To verify dynamic thread (OSS) creation.
11255 #
11256 test_115() {
11257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11258         remote_ost_nodsh && skip "remote OST with nodsh"
11259
11260         # Lustre does not stop service threads once they are started.
11261         # Reset number of running threads to default.
11262         stopall
11263         setupall
11264
11265         local OSTIO_pre
11266         local save_params="$TMP/sanity-$TESTNAME.parameters"
11267
11268         # Get ll_ost_io count before I/O
11269         OSTIO_pre=$(do_facet ost1 \
11270                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11271         # Exit if lustre is not running (ll_ost_io not running).
11272         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11273
11274         echo "Starting with $OSTIO_pre threads"
11275         local thread_max=$((OSTIO_pre * 2))
11276         local rpc_in_flight=$((thread_max * 2))
11277         # Number of I/O Process proposed to be started.
11278         local nfiles
11279         local facets=$(get_facets OST)
11280
11281         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11282         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11283
11284         # Set in_flight to $rpc_in_flight
11285         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11286                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11287         nfiles=${rpc_in_flight}
11288         # Set ost thread_max to $thread_max
11289         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11290
11291         # 5 Minutes should be sufficient for max number of OSS
11292         # threads(thread_max) to be created.
11293         local timeout=300
11294
11295         # Start I/O.
11296         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11297         test_mkdir $DIR/$tdir
11298         for i in $(seq $nfiles); do
11299                 local file=$DIR/$tdir/${tfile}-$i
11300                 $LFS setstripe -c -1 -i 0 $file
11301                 ($WTL $file $timeout)&
11302         done
11303
11304         # I/O Started - Wait for thread_started to reach thread_max or report
11305         # error if thread_started is more than thread_max.
11306         echo "Waiting for thread_started to reach thread_max"
11307         local thread_started=0
11308         local end_time=$((SECONDS + timeout))
11309
11310         while [ $SECONDS -le $end_time ] ; do
11311                 echo -n "."
11312                 # Get ost i/o thread_started count.
11313                 thread_started=$(do_facet ost1 \
11314                         "$LCTL get_param \
11315                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11316                 # Break out if thread_started is equal/greater than thread_max
11317                 if [[ $thread_started -ge $thread_max ]]; then
11318                         echo ll_ost_io thread_started $thread_started, \
11319                                 equal/greater than thread_max $thread_max
11320                         break
11321                 fi
11322                 sleep 1
11323         done
11324
11325         # Cleanup - We have the numbers, Kill i/o jobs if running.
11326         jobcount=($(jobs -p))
11327         for i in $(seq 0 $((${#jobcount[@]}-1)))
11328         do
11329                 kill -9 ${jobcount[$i]}
11330                 if [ $? -ne 0 ] ; then
11331                         echo Warning: \
11332                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11333                 fi
11334         done
11335
11336         # Cleanup files left by WTL binary.
11337         for i in $(seq $nfiles); do
11338                 local file=$DIR/$tdir/${tfile}-$i
11339                 rm -rf $file
11340                 if [ $? -ne 0 ] ; then
11341                         echo "Warning: Failed to delete file $file"
11342                 fi
11343         done
11344
11345         restore_lustre_params <$save_params
11346         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11347
11348         # Error out if no new thread has started or Thread started is greater
11349         # than thread max.
11350         if [[ $thread_started -le $OSTIO_pre ||
11351                         $thread_started -gt $thread_max ]]; then
11352                 error "ll_ost_io: thread_started $thread_started" \
11353                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11354                       "No new thread started or thread started greater " \
11355                       "than thread_max."
11356         fi
11357 }
11358 run_test 115 "verify dynamic thread creation===================="
11359
11360 free_min_max () {
11361         wait_delete_completed
11362         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11363         echo "OST kbytes available: ${AVAIL[@]}"
11364         MAXV=${AVAIL[0]}
11365         MAXI=0
11366         MINV=${AVAIL[0]}
11367         MINI=0
11368         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11369                 #echo OST $i: ${AVAIL[i]}kb
11370                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11371                         MAXV=${AVAIL[i]}
11372                         MAXI=$i
11373                 fi
11374                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11375                         MINV=${AVAIL[i]}
11376                         MINI=$i
11377                 fi
11378         done
11379         echo "Min free space: OST $MINI: $MINV"
11380         echo "Max free space: OST $MAXI: $MAXV"
11381 }
11382
11383 test_116a() { # was previously test_116()
11384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11386         remote_mds_nodsh && skip "remote MDS with nodsh"
11387
11388         echo -n "Free space priority "
11389         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11390                 head -n1
11391         declare -a AVAIL
11392         free_min_max
11393
11394         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11395         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11396         trap simple_cleanup_common EXIT
11397
11398         # Check if we need to generate uneven OSTs
11399         test_mkdir -p $DIR/$tdir/OST${MINI}
11400         local FILL=$((MINV / 4))
11401         local DIFF=$((MAXV - MINV))
11402         local DIFF2=$((DIFF * 100 / MINV))
11403
11404         local threshold=$(do_facet $SINGLEMDS \
11405                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11406         threshold=${threshold%%%}
11407         echo -n "Check for uneven OSTs: "
11408         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11409
11410         if [[ $DIFF2 -gt $threshold ]]; then
11411                 echo "ok"
11412                 echo "Don't need to fill OST$MINI"
11413         else
11414                 # generate uneven OSTs. Write 2% over the QOS threshold value
11415                 echo "no"
11416                 DIFF=$((threshold - DIFF2 + 2))
11417                 DIFF2=$((MINV * DIFF / 100))
11418                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11419                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11420                         error "setstripe failed"
11421                 DIFF=$((DIFF2 / 2048))
11422                 i=0
11423                 while [ $i -lt $DIFF ]; do
11424                         i=$((i + 1))
11425                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11426                                 bs=2M count=1 2>/dev/null
11427                         echo -n .
11428                 done
11429                 echo .
11430                 sync
11431                 sleep_maxage
11432                 free_min_max
11433         fi
11434
11435         DIFF=$((MAXV - MINV))
11436         DIFF2=$((DIFF * 100 / MINV))
11437         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11438         if [ $DIFF2 -gt $threshold ]; then
11439                 echo "ok"
11440         else
11441                 echo "failed - QOS mode won't be used"
11442                 simple_cleanup_common
11443                 skip "QOS imbalance criteria not met"
11444         fi
11445
11446         MINI1=$MINI
11447         MINV1=$MINV
11448         MAXI1=$MAXI
11449         MAXV1=$MAXV
11450
11451         # now fill using QOS
11452         $LFS setstripe -c 1 $DIR/$tdir
11453         FILL=$((FILL / 200))
11454         if [ $FILL -gt 600 ]; then
11455                 FILL=600
11456         fi
11457         echo "writing $FILL files to QOS-assigned OSTs"
11458         i=0
11459         while [ $i -lt $FILL ]; do
11460                 i=$((i + 1))
11461                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11462                         count=1 2>/dev/null
11463                 echo -n .
11464         done
11465         echo "wrote $i 200k files"
11466         sync
11467         sleep_maxage
11468
11469         echo "Note: free space may not be updated, so measurements might be off"
11470         free_min_max
11471         DIFF2=$((MAXV - MINV))
11472         echo "free space delta: orig $DIFF final $DIFF2"
11473         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11474         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11475         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11476         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11477         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11478         if [[ $DIFF -gt 0 ]]; then
11479                 FILL=$((DIFF2 * 100 / DIFF - 100))
11480                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11481         fi
11482
11483         # Figure out which files were written where
11484         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11485                awk '/'$MINI1': / {print $2; exit}')
11486         echo $UUID
11487         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11488         echo "$MINC files created on smaller OST $MINI1"
11489         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11490                awk '/'$MAXI1': / {print $2; exit}')
11491         echo $UUID
11492         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11493         echo "$MAXC files created on larger OST $MAXI1"
11494         if [[ $MINC -gt 0 ]]; then
11495                 FILL=$((MAXC * 100 / MINC - 100))
11496                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11497         fi
11498         [[ $MAXC -gt $MINC ]] ||
11499                 error_ignore LU-9 "stripe QOS didn't balance free space"
11500         simple_cleanup_common
11501 }
11502 run_test 116a "stripe QOS: free space balance ==================="
11503
11504 test_116b() { # LU-2093
11505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11506         remote_mds_nodsh && skip "remote MDS with nodsh"
11507
11508 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11509         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11510                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11511         [ -z "$old_rr" ] && skip "no QOS"
11512         do_facet $SINGLEMDS lctl set_param \
11513                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11514         mkdir -p $DIR/$tdir
11515         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11516         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11517         do_facet $SINGLEMDS lctl set_param fail_loc=0
11518         rm -rf $DIR/$tdir
11519         do_facet $SINGLEMDS lctl set_param \
11520                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11521 }
11522 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11523
11524 test_117() # bug 10891
11525 {
11526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11527
11528         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11529         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11530         lctl set_param fail_loc=0x21e
11531         > $DIR/$tfile || error "truncate failed"
11532         lctl set_param fail_loc=0
11533         echo "Truncate succeeded."
11534         rm -f $DIR/$tfile
11535 }
11536 run_test 117 "verify osd extend =========="
11537
11538 NO_SLOW_RESENDCOUNT=4
11539 export OLD_RESENDCOUNT=""
11540 set_resend_count () {
11541         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11542         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11543         lctl set_param -n $PROC_RESENDCOUNT $1
11544         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11545 }
11546
11547 # for reduce test_118* time (b=14842)
11548 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11549
11550 # Reset async IO behavior after error case
11551 reset_async() {
11552         FILE=$DIR/reset_async
11553
11554         # Ensure all OSCs are cleared
11555         $LFS setstripe -c -1 $FILE
11556         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11557         sync
11558         rm $FILE
11559 }
11560
11561 test_118a() #bug 11710
11562 {
11563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11564
11565         reset_async
11566
11567         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11568         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11569         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11570
11571         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11572                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11573                 return 1;
11574         fi
11575         rm -f $DIR/$tfile
11576 }
11577 run_test 118a "verify O_SYNC works =========="
11578
11579 test_118b()
11580 {
11581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11582         remote_ost_nodsh && skip "remote OST with nodsh"
11583
11584         reset_async
11585
11586         #define OBD_FAIL_SRV_ENOENT 0x217
11587         set_nodes_failloc "$(osts_nodes)" 0x217
11588         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11589         RC=$?
11590         set_nodes_failloc "$(osts_nodes)" 0
11591         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11592         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11593                     grep -c writeback)
11594
11595         if [[ $RC -eq 0 ]]; then
11596                 error "Must return error due to dropped pages, rc=$RC"
11597                 return 1;
11598         fi
11599
11600         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11601                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11602                 return 1;
11603         fi
11604
11605         echo "Dirty pages not leaked on ENOENT"
11606
11607         # Due to the above error the OSC will issue all RPCs syncronously
11608         # until a subsequent RPC completes successfully without error.
11609         $MULTIOP $DIR/$tfile Ow4096yc
11610         rm -f $DIR/$tfile
11611
11612         return 0
11613 }
11614 run_test 118b "Reclaim dirty pages on fatal error =========="
11615
11616 test_118c()
11617 {
11618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11619
11620         # for 118c, restore the original resend count, LU-1940
11621         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11622                                 set_resend_count $OLD_RESENDCOUNT
11623         remote_ost_nodsh && skip "remote OST with nodsh"
11624
11625         reset_async
11626
11627         #define OBD_FAIL_OST_EROFS               0x216
11628         set_nodes_failloc "$(osts_nodes)" 0x216
11629
11630         # multiop should block due to fsync until pages are written
11631         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11632         MULTIPID=$!
11633         sleep 1
11634
11635         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11636                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11637         fi
11638
11639         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11640                     grep -c writeback)
11641         if [[ $WRITEBACK -eq 0 ]]; then
11642                 error "No page in writeback, writeback=$WRITEBACK"
11643         fi
11644
11645         set_nodes_failloc "$(osts_nodes)" 0
11646         wait $MULTIPID
11647         RC=$?
11648         if [[ $RC -ne 0 ]]; then
11649                 error "Multiop fsync failed, rc=$RC"
11650         fi
11651
11652         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11653         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11654                     grep -c writeback)
11655         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11656                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11657         fi
11658
11659         rm -f $DIR/$tfile
11660         echo "Dirty pages flushed via fsync on EROFS"
11661         return 0
11662 }
11663 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11664
11665 # continue to use small resend count to reduce test_118* time (b=14842)
11666 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11667
11668 test_118d()
11669 {
11670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11671         remote_ost_nodsh && skip "remote OST with nodsh"
11672
11673         reset_async
11674
11675         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11676         set_nodes_failloc "$(osts_nodes)" 0x214
11677         # multiop should block due to fsync until pages are written
11678         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11679         MULTIPID=$!
11680         sleep 1
11681
11682         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11683                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11684         fi
11685
11686         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11687                     grep -c writeback)
11688         if [[ $WRITEBACK -eq 0 ]]; then
11689                 error "No page in writeback, writeback=$WRITEBACK"
11690         fi
11691
11692         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11693         set_nodes_failloc "$(osts_nodes)" 0
11694
11695         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11696         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11697                     grep -c writeback)
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 "Dirty pages gaurenteed flushed via fsync"
11704         return 0
11705 }
11706 run_test 118d "Fsync validation inject a delay of the bulk =========="
11707
11708 test_118f() {
11709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11710
11711         reset_async
11712
11713         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11714         lctl set_param fail_loc=0x8000040a
11715
11716         # Should simulate EINVAL error which is fatal
11717         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11718         RC=$?
11719         if [[ $RC -eq 0 ]]; then
11720                 error "Must return error due to dropped pages, rc=$RC"
11721         fi
11722
11723         lctl set_param fail_loc=0x0
11724
11725         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11726         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11727         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11728                     grep -c writeback)
11729         if [[ $LOCKED -ne 0 ]]; then
11730                 error "Locked pages remain in cache, locked=$LOCKED"
11731         fi
11732
11733         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11734                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11735         fi
11736
11737         rm -f $DIR/$tfile
11738         echo "No pages locked after fsync"
11739
11740         reset_async
11741         return 0
11742 }
11743 run_test 118f "Simulate unrecoverable OSC side error =========="
11744
11745 test_118g() {
11746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11747
11748         reset_async
11749
11750         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11751         lctl set_param fail_loc=0x406
11752
11753         # simulate local -ENOMEM
11754         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11755         RC=$?
11756
11757         lctl set_param fail_loc=0
11758         if [[ $RC -eq 0 ]]; then
11759                 error "Must return error due to dropped pages, rc=$RC"
11760         fi
11761
11762         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11763         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11764         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11765                         grep -c writeback)
11766         if [[ $LOCKED -ne 0 ]]; then
11767                 error "Locked pages remain in cache, locked=$LOCKED"
11768         fi
11769
11770         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11771                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11772         fi
11773
11774         rm -f $DIR/$tfile
11775         echo "No pages locked after fsync"
11776
11777         reset_async
11778         return 0
11779 }
11780 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11781
11782 test_118h() {
11783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11784         remote_ost_nodsh && skip "remote OST with nodsh"
11785
11786         reset_async
11787
11788         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11789         set_nodes_failloc "$(osts_nodes)" 0x20e
11790         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11791         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11792         RC=$?
11793
11794         set_nodes_failloc "$(osts_nodes)" 0
11795         if [[ $RC -eq 0 ]]; then
11796                 error "Must return error due to dropped pages, rc=$RC"
11797         fi
11798
11799         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11800         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11801         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11802                     grep -c writeback)
11803         if [[ $LOCKED -ne 0 ]]; then
11804                 error "Locked pages remain in cache, locked=$LOCKED"
11805         fi
11806
11807         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11808                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11809         fi
11810
11811         rm -f $DIR/$tfile
11812         echo "No pages locked after fsync"
11813
11814         return 0
11815 }
11816 run_test 118h "Verify timeout in handling recoverables errors  =========="
11817
11818 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11819
11820 test_118i() {
11821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11822         remote_ost_nodsh && skip "remote OST with nodsh"
11823
11824         reset_async
11825
11826         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11827         set_nodes_failloc "$(osts_nodes)" 0x20e
11828
11829         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11830         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11831         PID=$!
11832         sleep 5
11833         set_nodes_failloc "$(osts_nodes)" 0
11834
11835         wait $PID
11836         RC=$?
11837         if [[ $RC -ne 0 ]]; then
11838                 error "got error, but should be not, rc=$RC"
11839         fi
11840
11841         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11842         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11843         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11844         if [[ $LOCKED -ne 0 ]]; then
11845                 error "Locked pages remain in cache, locked=$LOCKED"
11846         fi
11847
11848         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11849                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11850         fi
11851
11852         rm -f $DIR/$tfile
11853         echo "No pages locked after fsync"
11854
11855         return 0
11856 }
11857 run_test 118i "Fix error before timeout in recoverable error  =========="
11858
11859 [ "$SLOW" = "no" ] && set_resend_count 4
11860
11861 test_118j() {
11862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11863         remote_ost_nodsh && skip "remote OST with nodsh"
11864
11865         reset_async
11866
11867         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11868         set_nodes_failloc "$(osts_nodes)" 0x220
11869
11870         # return -EIO from OST
11871         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11872         RC=$?
11873         set_nodes_failloc "$(osts_nodes)" 0x0
11874         if [[ $RC -eq 0 ]]; then
11875                 error "Must return error due to dropped pages, rc=$RC"
11876         fi
11877
11878         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11879         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11880         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11881         if [[ $LOCKED -ne 0 ]]; then
11882                 error "Locked pages remain in cache, locked=$LOCKED"
11883         fi
11884
11885         # in recoverable error on OST we want resend and stay until it finished
11886         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11887                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11888         fi
11889
11890         rm -f $DIR/$tfile
11891         echo "No pages locked after fsync"
11892
11893         return 0
11894 }
11895 run_test 118j "Simulate unrecoverable OST side error =========="
11896
11897 test_118k()
11898 {
11899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11900         remote_ost_nodsh && skip "remote OSTs with nodsh"
11901
11902         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11903         set_nodes_failloc "$(osts_nodes)" 0x20e
11904         test_mkdir $DIR/$tdir
11905
11906         for ((i=0;i<10;i++)); do
11907                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11908                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11909                 SLEEPPID=$!
11910                 sleep 0.500s
11911                 kill $SLEEPPID
11912                 wait $SLEEPPID
11913         done
11914
11915         set_nodes_failloc "$(osts_nodes)" 0
11916         rm -rf $DIR/$tdir
11917 }
11918 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11919
11920 test_118l() # LU-646
11921 {
11922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11923
11924         test_mkdir $DIR/$tdir
11925         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11926         rm -rf $DIR/$tdir
11927 }
11928 run_test 118l "fsync dir"
11929
11930 test_118m() # LU-3066
11931 {
11932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11933
11934         test_mkdir $DIR/$tdir
11935         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11936         rm -rf $DIR/$tdir
11937 }
11938 run_test 118m "fdatasync dir ========="
11939
11940 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11941
11942 test_118n()
11943 {
11944         local begin
11945         local end
11946
11947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11948         remote_ost_nodsh && skip "remote OSTs with nodsh"
11949
11950         # Sleep to avoid a cached response.
11951         #define OBD_STATFS_CACHE_SECONDS 1
11952         sleep 2
11953
11954         # Inject a 10 second delay in the OST_STATFS handler.
11955         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11956         set_nodes_failloc "$(osts_nodes)" 0x242
11957
11958         begin=$SECONDS
11959         stat --file-system $MOUNT > /dev/null
11960         end=$SECONDS
11961
11962         set_nodes_failloc "$(osts_nodes)" 0
11963
11964         if ((end - begin > 20)); then
11965             error "statfs took $((end - begin)) seconds, expected 10"
11966         fi
11967 }
11968 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11969
11970 test_119a() # bug 11737
11971 {
11972         BSIZE=$((512 * 1024))
11973         directio write $DIR/$tfile 0 1 $BSIZE
11974         # We ask to read two blocks, which is more than a file size.
11975         # directio will indicate an error when requested and actual
11976         # sizes aren't equeal (a normal situation in this case) and
11977         # print actual read amount.
11978         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11979         if [ "$NOB" != "$BSIZE" ]; then
11980                 error "read $NOB bytes instead of $BSIZE"
11981         fi
11982         rm -f $DIR/$tfile
11983 }
11984 run_test 119a "Short directIO read must return actual read amount"
11985
11986 test_119b() # bug 11737
11987 {
11988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11989
11990         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11992         sync
11993         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11994                 error "direct read failed"
11995         rm -f $DIR/$tfile
11996 }
11997 run_test 119b "Sparse directIO read must return actual read amount"
11998
11999 test_119c() # bug 13099
12000 {
12001         BSIZE=1048576
12002         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12003         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12004         rm -f $DIR/$tfile
12005 }
12006 run_test 119c "Testing for direct read hitting hole"
12007
12008 test_119d() # bug 15950
12009 {
12010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12011
12012         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12013         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12014         BSIZE=1048576
12015         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12016         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12017         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12018         lctl set_param fail_loc=0x40d
12019         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12020         pid_dio=$!
12021         sleep 1
12022         cat $DIR/$tfile > /dev/null &
12023         lctl set_param fail_loc=0
12024         pid_reads=$!
12025         wait $pid_dio
12026         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12027         sleep 2
12028         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12029         error "the read rpcs have not completed in 2s"
12030         rm -f $DIR/$tfile
12031         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12032 }
12033 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12034
12035 test_120a() {
12036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12037         remote_mds_nodsh && skip "remote MDS with nodsh"
12038         test_mkdir -i0 -c1 $DIR/$tdir
12039         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12040                 skip_env "no early lock cancel on server"
12041
12042         lru_resize_disable mdc
12043         lru_resize_disable osc
12044         cancel_lru_locks mdc
12045         # asynchronous object destroy at MDT could cause bl ast to client
12046         cancel_lru_locks osc
12047
12048         stat $DIR/$tdir > /dev/null
12049         can1=$(do_facet mds1 \
12050                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12051                awk '/ldlm_cancel/ {print $2}')
12052         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12053                awk '/ldlm_bl_callback/ {print $2}')
12054         test_mkdir -i0 -c1 $DIR/$tdir/d1
12055         can2=$(do_facet mds1 \
12056                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12057                awk '/ldlm_cancel/ {print $2}')
12058         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12059                awk '/ldlm_bl_callback/ {print $2}')
12060         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12061         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12062         lru_resize_enable mdc
12063         lru_resize_enable osc
12064 }
12065 run_test 120a "Early Lock Cancel: mkdir test"
12066
12067 test_120b() {
12068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12069         remote_mds_nodsh && skip "remote MDS with nodsh"
12070         test_mkdir $DIR/$tdir
12071         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12072                 skip_env "no early lock cancel on server"
12073
12074         lru_resize_disable mdc
12075         lru_resize_disable osc
12076         cancel_lru_locks mdc
12077         stat $DIR/$tdir > /dev/null
12078         can1=$(do_facet $SINGLEMDS \
12079                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12080                awk '/ldlm_cancel/ {print $2}')
12081         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12082                awk '/ldlm_bl_callback/ {print $2}')
12083         touch $DIR/$tdir/f1
12084         can2=$(do_facet $SINGLEMDS \
12085                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12086                awk '/ldlm_cancel/ {print $2}')
12087         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12088                awk '/ldlm_bl_callback/ {print $2}')
12089         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12090         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12091         lru_resize_enable mdc
12092         lru_resize_enable osc
12093 }
12094 run_test 120b "Early Lock Cancel: create test"
12095
12096 test_120c() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_mds_nodsh && skip "remote MDS with nodsh"
12099         test_mkdir -i0 -c1 $DIR/$tdir
12100         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12101                 skip "no early lock cancel on server"
12102
12103         lru_resize_disable mdc
12104         lru_resize_disable osc
12105         test_mkdir -i0 -c1 $DIR/$tdir/d1
12106         test_mkdir -i0 -c1 $DIR/$tdir/d2
12107         touch $DIR/$tdir/d1/f1
12108         cancel_lru_locks mdc
12109         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12110         can1=$(do_facet mds1 \
12111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12112                awk '/ldlm_cancel/ {print $2}')
12113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12114                awk '/ldlm_bl_callback/ {print $2}')
12115         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12116         can2=$(do_facet mds1 \
12117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12118                awk '/ldlm_cancel/ {print $2}')
12119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12120                awk '/ldlm_bl_callback/ {print $2}')
12121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12123         lru_resize_enable mdc
12124         lru_resize_enable osc
12125 }
12126 run_test 120c "Early Lock Cancel: link test"
12127
12128 test_120d() {
12129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12130         remote_mds_nodsh && skip "remote MDS with nodsh"
12131         test_mkdir -i0 -c1 $DIR/$tdir
12132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12133                 skip_env "no early lock cancel on server"
12134
12135         lru_resize_disable mdc
12136         lru_resize_disable osc
12137         touch $DIR/$tdir
12138         cancel_lru_locks mdc
12139         stat $DIR/$tdir > /dev/null
12140         can1=$(do_facet mds1 \
12141                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12142                awk '/ldlm_cancel/ {print $2}')
12143         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12144                awk '/ldlm_bl_callback/ {print $2}')
12145         chmod a+x $DIR/$tdir
12146         can2=$(do_facet mds1 \
12147                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12148                awk '/ldlm_cancel/ {print $2}')
12149         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12150                awk '/ldlm_bl_callback/ {print $2}')
12151         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12152         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12153         lru_resize_enable mdc
12154         lru_resize_enable osc
12155 }
12156 run_test 120d "Early Lock Cancel: setattr test"
12157
12158 test_120e() {
12159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12160         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12161                 skip_env "no early lock cancel on server"
12162         remote_mds_nodsh && skip "remote MDS with nodsh"
12163
12164         local dlmtrace_set=false
12165
12166         test_mkdir -i0 -c1 $DIR/$tdir
12167         lru_resize_disable mdc
12168         lru_resize_disable osc
12169         ! $LCTL get_param debug | grep -q dlmtrace &&
12170                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12171         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12172         cancel_lru_locks mdc
12173         cancel_lru_locks osc
12174         dd if=$DIR/$tdir/f1 of=/dev/null
12175         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12176         # XXX client can not do early lock cancel of OST lock
12177         # during unlink (LU-4206), so cancel osc lock now.
12178         sleep 2
12179         cancel_lru_locks osc
12180         can1=$(do_facet mds1 \
12181                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12182                awk '/ldlm_cancel/ {print $2}')
12183         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12184                awk '/ldlm_bl_callback/ {print $2}')
12185         unlink $DIR/$tdir/f1
12186         sleep 5
12187         can2=$(do_facet mds1 \
12188                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12189                awk '/ldlm_cancel/ {print $2}')
12190         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12191                awk '/ldlm_bl_callback/ {print $2}')
12192         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12193                 $LCTL dk $TMP/cancel.debug.txt
12194         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12195                 $LCTL dk $TMP/blocking.debug.txt
12196         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12197         lru_resize_enable mdc
12198         lru_resize_enable osc
12199 }
12200 run_test 120e "Early Lock Cancel: unlink test"
12201
12202 test_120f() {
12203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12204         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12205                 skip_env "no early lock cancel on server"
12206         remote_mds_nodsh && skip "remote MDS with nodsh"
12207
12208         test_mkdir -i0 -c1 $DIR/$tdir
12209         lru_resize_disable mdc
12210         lru_resize_disable osc
12211         test_mkdir -i0 -c1 $DIR/$tdir/d1
12212         test_mkdir -i0 -c1 $DIR/$tdir/d2
12213         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12214         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12215         cancel_lru_locks mdc
12216         cancel_lru_locks osc
12217         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12218         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12219         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12220         # XXX client can not do early lock cancel of OST lock
12221         # during rename (LU-4206), so cancel osc lock now.
12222         sleep 2
12223         cancel_lru_locks osc
12224         can1=$(do_facet mds1 \
12225                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12226                awk '/ldlm_cancel/ {print $2}')
12227         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12228                awk '/ldlm_bl_callback/ {print $2}')
12229         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12230         sleep 5
12231         can2=$(do_facet mds1 \
12232                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12233                awk '/ldlm_cancel/ {print $2}')
12234         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12235                awk '/ldlm_bl_callback/ {print $2}')
12236         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12237         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12238         lru_resize_enable mdc
12239         lru_resize_enable osc
12240 }
12241 run_test 120f "Early Lock Cancel: rename test"
12242
12243 test_120g() {
12244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12245         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12246                 skip_env "no early lock cancel on server"
12247         remote_mds_nodsh && skip "remote MDS with nodsh"
12248
12249         lru_resize_disable mdc
12250         lru_resize_disable osc
12251         count=10000
12252         echo create $count files
12253         test_mkdir $DIR/$tdir
12254         cancel_lru_locks mdc
12255         cancel_lru_locks osc
12256         t0=$(date +%s)
12257
12258         can0=$(do_facet $SINGLEMDS \
12259                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12260                awk '/ldlm_cancel/ {print $2}')
12261         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12262                awk '/ldlm_bl_callback/ {print $2}')
12263         createmany -o $DIR/$tdir/f $count
12264         sync
12265         can1=$(do_facet $SINGLEMDS \
12266                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12267                awk '/ldlm_cancel/ {print $2}')
12268         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12269                awk '/ldlm_bl_callback/ {print $2}')
12270         t1=$(date +%s)
12271         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12272         echo rm $count files
12273         rm -r $DIR/$tdir
12274         sync
12275         can2=$(do_facet $SINGLEMDS \
12276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12277                awk '/ldlm_cancel/ {print $2}')
12278         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12279                awk '/ldlm_bl_callback/ {print $2}')
12280         t2=$(date +%s)
12281         echo total: $count removes in $((t2-t1))
12282         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12283         sleep 2
12284         # wait for commitment of removal
12285         lru_resize_enable mdc
12286         lru_resize_enable osc
12287 }
12288 run_test 120g "Early Lock Cancel: performance test"
12289
12290 test_121() { #bug #10589
12291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12292
12293         rm -rf $DIR/$tfile
12294         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12295 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12296         lctl set_param fail_loc=0x310
12297         cancel_lru_locks osc > /dev/null
12298         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12299         lctl set_param fail_loc=0
12300         [[ $reads -eq $writes ]] ||
12301                 error "read $reads blocks, must be $writes blocks"
12302 }
12303 run_test 121 "read cancel race ========="
12304
12305 test_123a_base() { # was test 123, statahead(bug 11401)
12306         local lsx="$1"
12307
12308         SLOWOK=0
12309         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12310                 log "testing UP system. Performance may be lower than expected."
12311                 SLOWOK=1
12312         fi
12313
12314         rm -rf $DIR/$tdir
12315         test_mkdir $DIR/$tdir
12316         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12317         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12318         MULT=10
12319         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12320                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12321
12322                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12323                 lctl set_param -n llite.*.statahead_max 0
12324                 lctl get_param llite.*.statahead_max
12325                 cancel_lru_locks mdc
12326                 cancel_lru_locks osc
12327                 stime=$(date +%s)
12328                 time $lsx $DIR/$tdir | wc -l
12329                 etime=$(date +%s)
12330                 delta=$((etime - stime))
12331                 log "$lsx $i files without statahead: $delta sec"
12332                 lctl set_param llite.*.statahead_max=$max
12333
12334                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12335                         grep "statahead wrong:" | awk '{print $3}')
12336                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12337                 cancel_lru_locks mdc
12338                 cancel_lru_locks osc
12339                 stime=$(date +%s)
12340                 time $lsx $DIR/$tdir | wc -l
12341                 etime=$(date +%s)
12342                 delta_sa=$((etime - stime))
12343                 log "$lsx $i files with statahead: $delta_sa sec"
12344                 lctl get_param -n llite.*.statahead_stats
12345                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12346                         grep "statahead wrong:" | awk '{print $3}')
12347
12348                 [[ $swrong -lt $ewrong ]] &&
12349                         log "statahead was stopped, maybe too many locks held!"
12350                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12351
12352                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12353                         max=$(lctl get_param -n llite.*.statahead_max |
12354                                 head -n 1)
12355                         lctl set_param -n llite.*.statahead_max 0
12356                         lctl get_param llite.*.statahead_max
12357                         cancel_lru_locks mdc
12358                         cancel_lru_locks osc
12359                         stime=$(date +%s)
12360                         time $lsx $DIR/$tdir | wc -l
12361                         etime=$(date +%s)
12362                         delta=$((etime - stime))
12363                         log "$lsx $i files again without statahead: $delta sec"
12364                         lctl set_param llite.*.statahead_max=$max
12365                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12366                                 if [  $SLOWOK -eq 0 ]; then
12367                                         error "$lsx $i files is slower with statahead!"
12368                                 else
12369                                         log "$lsx $i files is slower with statahead!"
12370                                 fi
12371                                 break
12372                         fi
12373                 fi
12374
12375                 [ $delta -gt 20 ] && break
12376                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12377                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12378         done
12379         log "$lsx done"
12380
12381         stime=$(date +%s)
12382         rm -r $DIR/$tdir
12383         sync
12384         etime=$(date +%s)
12385         delta=$((etime - stime))
12386         log "rm -r $DIR/$tdir/: $delta seconds"
12387         log "rm done"
12388         lctl get_param -n llite.*.statahead_stats
12389 }
12390
12391 test_123aa() {
12392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12393
12394         test_123a_base "ls -l"
12395 }
12396 run_test 123aa "verify statahead work"
12397
12398 test_123ab() {
12399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12400
12401         statx_supported || skip_env "Test must be statx() syscall supported"
12402
12403         test_123a_base "$STATX -l"
12404 }
12405 run_test 123ab "verify statahead work by using statx"
12406
12407 test_123ac() {
12408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12409
12410         statx_supported || skip_env "Test must be statx() syscall supported"
12411
12412         local rpcs_before
12413         local rpcs_after
12414         local agl_before
12415         local agl_after
12416
12417         cancel_lru_locks $OSC
12418         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12419         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12420                 awk '/agl.total:/ {print $3}')
12421         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12422         test_123a_base "$STATX --cached=always -D"
12423         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12424                 awk '/agl.total:/ {print $3}')
12425         [ $agl_before -eq $agl_after ] ||
12426                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12427         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12428         [ $rpcs_after -eq $rpcs_before ] ||
12429                 error "$STATX should not send glimpse RPCs to $OSC"
12430 }
12431 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12432
12433 test_123b () { # statahead(bug 15027)
12434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12435
12436         test_mkdir $DIR/$tdir
12437         createmany -o $DIR/$tdir/$tfile-%d 1000
12438
12439         cancel_lru_locks mdc
12440         cancel_lru_locks osc
12441
12442 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12443         lctl set_param fail_loc=0x80000803
12444         ls -lR $DIR/$tdir > /dev/null
12445         log "ls done"
12446         lctl set_param fail_loc=0x0
12447         lctl get_param -n llite.*.statahead_stats
12448         rm -r $DIR/$tdir
12449         sync
12450
12451 }
12452 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12453
12454 test_123c() {
12455         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12456
12457         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12458         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12459         touch $DIR/$tdir.1/{1..3}
12460         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12461
12462         remount_client $MOUNT
12463
12464         $MULTIOP $DIR/$tdir.0 Q
12465
12466         # let statahead to complete
12467         ls -l $DIR/$tdir.0 > /dev/null
12468
12469         testid=$(echo $TESTNAME | tr '_' ' ')
12470         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12471                 error "statahead warning" || true
12472 }
12473 run_test 123c "Can not initialize inode warning on DNE statahead"
12474
12475 test_124a() {
12476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12477         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12478                 skip_env "no lru resize on server"
12479
12480         local NR=2000
12481
12482         test_mkdir $DIR/$tdir
12483
12484         log "create $NR files at $DIR/$tdir"
12485         createmany -o $DIR/$tdir/f $NR ||
12486                 error "failed to create $NR files in $DIR/$tdir"
12487
12488         cancel_lru_locks mdc
12489         ls -l $DIR/$tdir > /dev/null
12490
12491         local NSDIR=""
12492         local LRU_SIZE=0
12493         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12494                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12495                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12496                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12497                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12498                         log "NSDIR=$NSDIR"
12499                         log "NS=$(basename $NSDIR)"
12500                         break
12501                 fi
12502         done
12503
12504         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12505                 skip "Not enough cached locks created!"
12506         fi
12507         log "LRU=$LRU_SIZE"
12508
12509         local SLEEP=30
12510
12511         # We know that lru resize allows one client to hold $LIMIT locks
12512         # for 10h. After that locks begin to be killed by client.
12513         local MAX_HRS=10
12514         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12515         log "LIMIT=$LIMIT"
12516         if [ $LIMIT -lt $LRU_SIZE ]; then
12517                 skip "Limit is too small $LIMIT"
12518         fi
12519
12520         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12521         # killing locks. Some time was spent for creating locks. This means
12522         # that up to the moment of sleep finish we must have killed some of
12523         # them (10-100 locks). This depends on how fast ther were created.
12524         # Many of them were touched in almost the same moment and thus will
12525         # be killed in groups.
12526         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12527
12528         # Use $LRU_SIZE_B here to take into account real number of locks
12529         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12530         local LRU_SIZE_B=$LRU_SIZE
12531         log "LVF=$LVF"
12532         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12533         log "OLD_LVF=$OLD_LVF"
12534         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12535
12536         # Let's make sure that we really have some margin. Client checks
12537         # cached locks every 10 sec.
12538         SLEEP=$((SLEEP+20))
12539         log "Sleep ${SLEEP} sec"
12540         local SEC=0
12541         while ((SEC<$SLEEP)); do
12542                 echo -n "..."
12543                 sleep 5
12544                 SEC=$((SEC+5))
12545                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12546                 echo -n "$LRU_SIZE"
12547         done
12548         echo ""
12549         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12550         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12551
12552         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12553                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12554                 unlinkmany $DIR/$tdir/f $NR
12555                 return
12556         }
12557
12558         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12559         log "unlink $NR files at $DIR/$tdir"
12560         unlinkmany $DIR/$tdir/f $NR
12561 }
12562 run_test 124a "lru resize ======================================="
12563
12564 get_max_pool_limit()
12565 {
12566         local limit=$($LCTL get_param \
12567                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12568         local max=0
12569         for l in $limit; do
12570                 if [[ $l -gt $max ]]; then
12571                         max=$l
12572                 fi
12573         done
12574         echo $max
12575 }
12576
12577 test_124b() {
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12580                 skip_env "no lru resize on server"
12581
12582         LIMIT=$(get_max_pool_limit)
12583
12584         NR=$(($(default_lru_size)*20))
12585         if [[ $NR -gt $LIMIT ]]; then
12586                 log "Limit lock number by $LIMIT locks"
12587                 NR=$LIMIT
12588         fi
12589
12590         IFree=$(mdsrate_inodes_available)
12591         if [ $IFree -lt $NR ]; then
12592                 log "Limit lock number by $IFree inodes"
12593                 NR=$IFree
12594         fi
12595
12596         lru_resize_disable mdc
12597         test_mkdir -p $DIR/$tdir/disable_lru_resize
12598
12599         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12600         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12601         cancel_lru_locks mdc
12602         stime=`date +%s`
12603         PID=""
12604         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12605         PID="$PID $!"
12606         sleep 2
12607         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12608         PID="$PID $!"
12609         sleep 2
12610         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12611         PID="$PID $!"
12612         wait $PID
12613         etime=`date +%s`
12614         nolruresize_delta=$((etime-stime))
12615         log "ls -la time: $nolruresize_delta seconds"
12616         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12617         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12618
12619         lru_resize_enable mdc
12620         test_mkdir -p $DIR/$tdir/enable_lru_resize
12621
12622         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12623         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12624         cancel_lru_locks mdc
12625         stime=`date +%s`
12626         PID=""
12627         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12628         PID="$PID $!"
12629         sleep 2
12630         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12631         PID="$PID $!"
12632         sleep 2
12633         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12634         PID="$PID $!"
12635         wait $PID
12636         etime=`date +%s`
12637         lruresize_delta=$((etime-stime))
12638         log "ls -la time: $lruresize_delta seconds"
12639         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12640
12641         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12642                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12643         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12644                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12645         else
12646                 log "lru resize performs the same with no lru resize"
12647         fi
12648         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12649 }
12650 run_test 124b "lru resize (performance test) ======================="
12651
12652 test_124c() {
12653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12654         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12655                 skip_env "no lru resize on server"
12656
12657         # cache ununsed locks on client
12658         local nr=100
12659         cancel_lru_locks mdc
12660         test_mkdir $DIR/$tdir
12661         createmany -o $DIR/$tdir/f $nr ||
12662                 error "failed to create $nr files in $DIR/$tdir"
12663         ls -l $DIR/$tdir > /dev/null
12664
12665         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12666         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12667         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12668         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12669         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12670
12671         # set lru_max_age to 1 sec
12672         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12673         echo "sleep $((recalc_p * 2)) seconds..."
12674         sleep $((recalc_p * 2))
12675
12676         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12677         # restore lru_max_age
12678         $LCTL set_param -n $nsdir.lru_max_age $max_age
12679         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12680         unlinkmany $DIR/$tdir/f $nr
12681 }
12682 run_test 124c "LRUR cancel very aged locks"
12683
12684 test_124d() {
12685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12686         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12687                 skip_env "no lru resize on server"
12688
12689         # cache ununsed locks on client
12690         local nr=100
12691
12692         lru_resize_disable mdc
12693         stack_trap "lru_resize_enable mdc" EXIT
12694
12695         cancel_lru_locks mdc
12696
12697         # asynchronous object destroy at MDT could cause bl ast to client
12698         test_mkdir $DIR/$tdir
12699         createmany -o $DIR/$tdir/f $nr ||
12700                 error "failed to create $nr files in $DIR/$tdir"
12701         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12702
12703         ls -l $DIR/$tdir > /dev/null
12704
12705         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12706         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12707         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12708         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12709
12710         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12711
12712         # set lru_max_age to 1 sec
12713         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12714         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12715
12716         echo "sleep $((recalc_p * 2)) seconds..."
12717         sleep $((recalc_p * 2))
12718
12719         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12720
12721         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12722 }
12723 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12724
12725 test_125() { # 13358
12726         $LCTL get_param -n llite.*.client_type | grep -q local ||
12727                 skip "must run as local client"
12728         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12729                 skip_env "must have acl enabled"
12730         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12731
12732         test_mkdir $DIR/$tdir
12733         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12734         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12735         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12736 }
12737 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12738
12739 test_126() { # bug 12829/13455
12740         $GSS && skip_env "must run as gss disabled"
12741         $LCTL get_param -n llite.*.client_type | grep -q local ||
12742                 skip "must run as local client"
12743         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12744
12745         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12746         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12747         rm -f $DIR/$tfile
12748         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12749 }
12750 run_test 126 "check that the fsgid provided by the client is taken into account"
12751
12752 test_127a() { # bug 15521
12753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12754         local name count samp unit min max sum sumsq
12755
12756         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12757         echo "stats before reset"
12758         $LCTL get_param osc.*.stats
12759         $LCTL set_param osc.*.stats=0
12760         local fsize=$((2048 * 1024))
12761
12762         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12763         cancel_lru_locks osc
12764         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12765
12766         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12767         stack_trap "rm -f $TMP/$tfile.tmp"
12768         while read name count samp unit min max sum sumsq; do
12769                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12770                 [ ! $min ] && error "Missing min value for $name proc entry"
12771                 eval $name=$count || error "Wrong proc format"
12772
12773                 case $name in
12774                 read_bytes|write_bytes)
12775                         [[ "$unit" =~ "bytes" ]] ||
12776                                 error "unit is not 'bytes': $unit"
12777                         (( $min >= 4096 )) || error "min is too small: $min"
12778                         (( $min <= $fsize )) || error "min is too big: $min"
12779                         (( $max >= 4096 )) || error "max is too small: $max"
12780                         (( $max <= $fsize )) || error "max is too big: $max"
12781                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12782                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12783                                 error "sumsquare is too small: $sumsq"
12784                         (( $sumsq <= $fsize * $fsize )) ||
12785                                 error "sumsquare is too big: $sumsq"
12786                         ;;
12787                 ost_read|ost_write)
12788                         [[ "$unit" =~ "usec" ]] ||
12789                                 error "unit is not 'usec': $unit"
12790                         ;;
12791                 *)      ;;
12792                 esac
12793         done < $DIR/$tfile.tmp
12794
12795         #check that we actually got some stats
12796         [ "$read_bytes" ] || error "Missing read_bytes stats"
12797         [ "$write_bytes" ] || error "Missing write_bytes stats"
12798         [ "$read_bytes" != 0 ] || error "no read done"
12799         [ "$write_bytes" != 0 ] || error "no write done"
12800 }
12801 run_test 127a "verify the client stats are sane"
12802
12803 test_127b() { # bug LU-333
12804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12805         local name count samp unit min max sum sumsq
12806
12807         echo "stats before reset"
12808         $LCTL get_param llite.*.stats
12809         $LCTL set_param llite.*.stats=0
12810
12811         # perform 2 reads and writes so MAX is different from SUM.
12812         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12813         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12814         cancel_lru_locks osc
12815         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12816         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12817
12818         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12819         stack_trap "rm -f $TMP/$tfile.tmp"
12820         while read name count samp unit min max sum sumsq; do
12821                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12822                 eval $name=$count || error "Wrong proc format"
12823
12824                 case $name in
12825                 read_bytes|write_bytes)
12826                         [[ "$unit" =~ "bytes" ]] ||
12827                                 error "unit is not 'bytes': $unit"
12828                         (( $count == 2 )) || error "count is not 2: $count"
12829                         (( $min == $PAGE_SIZE )) ||
12830                                 error "min is not $PAGE_SIZE: $min"
12831                         (( $max == $PAGE_SIZE )) ||
12832                                 error "max is not $PAGE_SIZE: $max"
12833                         (( $sum == $PAGE_SIZE * 2 )) ||
12834                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12835                         ;;
12836                 read|write)
12837                         [[ "$unit" =~ "usec" ]] ||
12838                                 error "unit is not 'usec': $unit"
12839                         ;;
12840                 *)      ;;
12841                 esac
12842         done < $TMP/$tfile.tmp
12843
12844         #check that we actually got some stats
12845         [ "$read_bytes" ] || error "Missing read_bytes stats"
12846         [ "$write_bytes" ] || error "Missing write_bytes stats"
12847         [ "$read_bytes" != 0 ] || error "no read done"
12848         [ "$write_bytes" != 0 ] || error "no write done"
12849 }
12850 run_test 127b "verify the llite client stats are sane"
12851
12852 test_127c() { # LU-12394
12853         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12854         local size
12855         local bsize
12856         local reads
12857         local writes
12858         local count
12859
12860         $LCTL set_param llite.*.extents_stats=1
12861         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12862
12863         # Use two stripes so there is enough space in default config
12864         $LFS setstripe -c 2 $DIR/$tfile
12865
12866         # Extent stats start at 0-4K and go in power of two buckets
12867         # LL_HIST_START = 12 --> 2^12 = 4K
12868         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12869         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12870         # small configs
12871         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12872                 do
12873                 # Write and read, 2x each, second time at a non-zero offset
12874                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12875                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12876                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12877                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12878                 rm -f $DIR/$tfile
12879         done
12880
12881         $LCTL get_param llite.*.extents_stats
12882
12883         count=2
12884         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12885                 do
12886                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12887                                 grep -m 1 $bsize)
12888                 reads=$(echo $bucket | awk '{print $5}')
12889                 writes=$(echo $bucket | awk '{print $9}')
12890                 [ "$reads" -eq $count ] ||
12891                         error "$reads reads in < $bsize bucket, expect $count"
12892                 [ "$writes" -eq $count ] ||
12893                         error "$writes writes in < $bsize bucket, expect $count"
12894         done
12895
12896         # Test mmap write and read
12897         $LCTL set_param llite.*.extents_stats=c
12898         size=512
12899         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12900         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12901         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12902
12903         $LCTL get_param llite.*.extents_stats
12904
12905         count=$(((size*1024) / PAGE_SIZE))
12906
12907         bsize=$((2 * PAGE_SIZE / 1024))K
12908
12909         bucket=$($LCTL get_param -n llite.*.extents_stats |
12910                         grep -m 1 $bsize)
12911         reads=$(echo $bucket | awk '{print $5}')
12912         writes=$(echo $bucket | awk '{print $9}')
12913         # mmap writes fault in the page first, creating an additonal read
12914         [ "$reads" -eq $((2 * count)) ] ||
12915                 error "$reads reads in < $bsize bucket, expect $count"
12916         [ "$writes" -eq $count ] ||
12917                 error "$writes writes in < $bsize bucket, expect $count"
12918 }
12919 run_test 127c "test llite extent stats with regular & mmap i/o"
12920
12921 test_128() { # bug 15212
12922         touch $DIR/$tfile
12923         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12924                 find $DIR/$tfile
12925                 find $DIR/$tfile
12926         EOF
12927
12928         result=$(grep error $TMP/$tfile.log)
12929         rm -f $DIR/$tfile $TMP/$tfile.log
12930         [ -z "$result" ] ||
12931                 error "consecutive find's under interactive lfs failed"
12932 }
12933 run_test 128 "interactive lfs for 2 consecutive find's"
12934
12935 set_dir_limits () {
12936         local mntdev
12937         local canondev
12938         local node
12939
12940         local ldproc=/proc/fs/ldiskfs
12941         local facets=$(get_facets MDS)
12942
12943         for facet in ${facets//,/ }; do
12944                 canondev=$(ldiskfs_canon \
12945                            *.$(convert_facet2label $facet).mntdev $facet)
12946                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12947                         ldproc=/sys/fs/ldiskfs
12948                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12949                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12950         done
12951 }
12952
12953 check_mds_dmesg() {
12954         local facets=$(get_facets MDS)
12955         for facet in ${facets//,/ }; do
12956                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12957         done
12958         return 1
12959 }
12960
12961 test_129() {
12962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12963         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12964                 skip "Need MDS version with at least 2.5.56"
12965         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12966                 skip_env "ldiskfs only test"
12967         fi
12968         remote_mds_nodsh && skip "remote MDS with nodsh"
12969
12970         local ENOSPC=28
12971         local has_warning=false
12972
12973         rm -rf $DIR/$tdir
12974         mkdir -p $DIR/$tdir
12975
12976         # block size of mds1
12977         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12978         set_dir_limits $maxsize $((maxsize * 6 / 8))
12979         stack_trap "set_dir_limits 0 0"
12980         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12981         local dirsize=$(stat -c%s "$DIR/$tdir")
12982         local nfiles=0
12983         while (( $dirsize <= $maxsize )); do
12984                 $MCREATE $DIR/$tdir/file_base_$nfiles
12985                 rc=$?
12986                 # check two errors:
12987                 # ENOSPC for ext4 max_dir_size, which has been used since
12988                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12989                 if (( rc == ENOSPC )); then
12990                         set_dir_limits 0 0
12991                         echo "rc=$rc returned as expected after $nfiles files"
12992
12993                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12994                                 error "create failed w/o dir size limit"
12995
12996                         # messages may be rate limited if test is run repeatedly
12997                         check_mds_dmesg '"is approaching max"' ||
12998                                 echo "warning message should be output"
12999                         check_mds_dmesg '"has reached max"' ||
13000                                 echo "reached message should be output"
13001
13002                         dirsize=$(stat -c%s "$DIR/$tdir")
13003
13004                         [[ $dirsize -ge $maxsize ]] && return 0
13005                         error "dirsize $dirsize < $maxsize after $nfiles files"
13006                 elif (( rc != 0 )); then
13007                         break
13008                 fi
13009                 nfiles=$((nfiles + 1))
13010                 dirsize=$(stat -c%s "$DIR/$tdir")
13011         done
13012
13013         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13014 }
13015 run_test 129 "test directory size limit ========================"
13016
13017 OLDIFS="$IFS"
13018 cleanup_130() {
13019         trap 0
13020         IFS="$OLDIFS"
13021 }
13022
13023 test_130a() {
13024         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13025         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13026
13027         trap cleanup_130 EXIT RETURN
13028
13029         local fm_file=$DIR/$tfile
13030         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13031         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13032                 error "dd failed for $fm_file"
13033
13034         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13035         filefrag -ves $fm_file
13036         RC=$?
13037         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13038                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13039         [ $RC != 0 ] && error "filefrag $fm_file failed"
13040
13041         filefrag_op=$(filefrag -ve -k $fm_file |
13042                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13043         lun=$($LFS getstripe -i $fm_file)
13044
13045         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13046         IFS=$'\n'
13047         tot_len=0
13048         for line in $filefrag_op
13049         do
13050                 frag_lun=`echo $line | cut -d: -f5`
13051                 ext_len=`echo $line | cut -d: -f4`
13052                 if (( $frag_lun != $lun )); then
13053                         cleanup_130
13054                         error "FIEMAP on 1-stripe file($fm_file) failed"
13055                         return
13056                 fi
13057                 (( tot_len += ext_len ))
13058         done
13059
13060         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13061                 cleanup_130
13062                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13063                 return
13064         fi
13065
13066         cleanup_130
13067
13068         echo "FIEMAP on single striped file succeeded"
13069 }
13070 run_test 130a "FIEMAP (1-stripe file)"
13071
13072 test_130b() {
13073         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13074
13075         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13076         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13077
13078         trap cleanup_130 EXIT RETURN
13079
13080         local fm_file=$DIR/$tfile
13081         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13082                         error "setstripe on $fm_file"
13083         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13084                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13085
13086         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13087                 error "dd failed on $fm_file"
13088
13089         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13090         filefrag_op=$(filefrag -ve -k $fm_file |
13091                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13092
13093         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13094                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13095
13096         IFS=$'\n'
13097         tot_len=0
13098         num_luns=1
13099         for line in $filefrag_op
13100         do
13101                 frag_lun=$(echo $line | cut -d: -f5 |
13102                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13103                 ext_len=$(echo $line | cut -d: -f4)
13104                 if (( $frag_lun != $last_lun )); then
13105                         if (( tot_len != 1024 )); then
13106                                 cleanup_130
13107                                 error "FIEMAP on $fm_file failed; returned " \
13108                                 "len $tot_len for OST $last_lun instead of 1024"
13109                                 return
13110                         else
13111                                 (( num_luns += 1 ))
13112                                 tot_len=0
13113                         fi
13114                 fi
13115                 (( tot_len += ext_len ))
13116                 last_lun=$frag_lun
13117         done
13118         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13119                 cleanup_130
13120                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13121                         "luns or wrong len for OST $last_lun"
13122                 return
13123         fi
13124
13125         cleanup_130
13126
13127         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13128 }
13129 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13130
13131 test_130c() {
13132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13133
13134         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13135         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13136
13137         trap cleanup_130 EXIT RETURN
13138
13139         local fm_file=$DIR/$tfile
13140         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13141         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13142                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13143
13144         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13145                         error "dd failed on $fm_file"
13146
13147         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13148         filefrag_op=$(filefrag -ve -k $fm_file |
13149                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13150
13151         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13152                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13153
13154         IFS=$'\n'
13155         tot_len=0
13156         num_luns=1
13157         for line in $filefrag_op
13158         do
13159                 frag_lun=$(echo $line | cut -d: -f5 |
13160                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13161                 ext_len=$(echo $line | cut -d: -f4)
13162                 if (( $frag_lun != $last_lun )); then
13163                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13164                         if (( logical != 512 )); then
13165                                 cleanup_130
13166                                 error "FIEMAP on $fm_file failed; returned " \
13167                                 "logical start for lun $logical instead of 512"
13168                                 return
13169                         fi
13170                         if (( tot_len != 512 )); then
13171                                 cleanup_130
13172                                 error "FIEMAP on $fm_file failed; returned " \
13173                                 "len $tot_len for OST $last_lun instead of 1024"
13174                                 return
13175                         else
13176                                 (( num_luns += 1 ))
13177                                 tot_len=0
13178                         fi
13179                 fi
13180                 (( tot_len += ext_len ))
13181                 last_lun=$frag_lun
13182         done
13183         if (( num_luns != 2 || tot_len != 512 )); then
13184                 cleanup_130
13185                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13186                         "luns or wrong len for OST $last_lun"
13187                 return
13188         fi
13189
13190         cleanup_130
13191
13192         echo "FIEMAP on 2-stripe file with hole succeeded"
13193 }
13194 run_test 130c "FIEMAP (2-stripe file with hole)"
13195
13196 test_130d() {
13197         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13198
13199         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13200         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13201
13202         trap cleanup_130 EXIT RETURN
13203
13204         local fm_file=$DIR/$tfile
13205         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13206                         error "setstripe on $fm_file"
13207         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13208                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13209
13210         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13211         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13212                 error "dd failed on $fm_file"
13213
13214         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13215         filefrag_op=$(filefrag -ve -k $fm_file |
13216                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13217
13218         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13219                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13220
13221         IFS=$'\n'
13222         tot_len=0
13223         num_luns=1
13224         for line in $filefrag_op
13225         do
13226                 frag_lun=$(echo $line | cut -d: -f5 |
13227                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13228                 ext_len=$(echo $line | cut -d: -f4)
13229                 if (( $frag_lun != $last_lun )); then
13230                         if (( tot_len != 1024 )); then
13231                                 cleanup_130
13232                                 error "FIEMAP on $fm_file failed; returned " \
13233                                 "len $tot_len for OST $last_lun instead of 1024"
13234                                 return
13235                         else
13236                                 (( num_luns += 1 ))
13237                                 tot_len=0
13238                         fi
13239                 fi
13240                 (( tot_len += ext_len ))
13241                 last_lun=$frag_lun
13242         done
13243         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13244                 cleanup_130
13245                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13246                         "luns or wrong len for OST $last_lun"
13247                 return
13248         fi
13249
13250         cleanup_130
13251
13252         echo "FIEMAP on N-stripe file succeeded"
13253 }
13254 run_test 130d "FIEMAP (N-stripe file)"
13255
13256 test_130e() {
13257         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13258
13259         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13260         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13261
13262         trap cleanup_130 EXIT RETURN
13263
13264         local fm_file=$DIR/$tfile
13265         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13266
13267         NUM_BLKS=512
13268         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13269         for ((i = 0; i < $NUM_BLKS; i++)); do
13270                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13271                         conv=notrunc > /dev/null 2>&1
13272         done
13273
13274         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13275         filefrag_op=$(filefrag -ve -k $fm_file |
13276                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13277
13278         last_lun=$(echo $filefrag_op | cut -d: -f5)
13279
13280         IFS=$'\n'
13281         tot_len=0
13282         num_luns=1
13283         for line in $filefrag_op; do
13284                 frag_lun=$(echo $line | cut -d: -f5)
13285                 ext_len=$(echo $line | cut -d: -f4)
13286                 if [[ "$frag_lun" != "$last_lun" ]]; then
13287                         if (( tot_len != $EXPECTED_LEN )); then
13288                                 cleanup_130
13289                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13290                         else
13291                                 (( num_luns += 1 ))
13292                                 tot_len=0
13293                         fi
13294                 fi
13295                 (( tot_len += ext_len ))
13296                 last_lun=$frag_lun
13297         done
13298         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13299                 cleanup_130
13300                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13301         fi
13302
13303         echo "FIEMAP with continuation calls succeeded"
13304 }
13305 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13306
13307 test_130f() {
13308         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13309         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13310
13311         local fm_file=$DIR/$tfile
13312         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13313                 error "multiop create with lov_delay_create on $fm_file"
13314
13315         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13316         filefrag_extents=$(filefrag -vek $fm_file |
13317                            awk '/extents? found/ { print $2 }')
13318         if [[ "$filefrag_extents" != "0" ]]; then
13319                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13320         fi
13321
13322         rm -f $fm_file
13323 }
13324 run_test 130f "FIEMAP (unstriped file)"
13325
13326 test_130g() {
13327         local file=$DIR/$tfile
13328         local nr=$((OSTCOUNT * 100))
13329
13330         $LFS setstripe -C $nr $file ||
13331                 error "failed to setstripe -C $nr $file"
13332
13333         dd if=/dev/zero of=$file count=$nr bs=1M
13334         sync
13335         nr=$($LFS getstripe -c $file)
13336
13337         local extents=$(filefrag -v $file |
13338                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13339
13340         echo "filefrag list $extents extents in file with stripecount $nr"
13341         if (( extents < nr )); then
13342                 $LFS getstripe $file
13343                 filefrag -v $file
13344                 error "filefrag printed $extents < $nr extents"
13345         fi
13346
13347         rm -f $file
13348 }
13349 run_test 130g "FIEMAP (overstripe file)"
13350
13351 # Test for writev/readv
13352 test_131a() {
13353         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13354                 error "writev test failed"
13355         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13356                 error "readv failed"
13357         rm -f $DIR/$tfile
13358 }
13359 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13360
13361 test_131b() {
13362         local fsize=$((524288 + 1048576 + 1572864))
13363         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13364                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13365                         error "append writev test failed"
13366
13367         ((fsize += 1572864 + 1048576))
13368         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13369                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13370                         error "append writev test failed"
13371         rm -f $DIR/$tfile
13372 }
13373 run_test 131b "test append writev"
13374
13375 test_131c() {
13376         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13377         error "NOT PASS"
13378 }
13379 run_test 131c "test read/write on file w/o objects"
13380
13381 test_131d() {
13382         rwv -f $DIR/$tfile -w -n 1 1572864
13383         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13384         if [ "$NOB" != 1572864 ]; then
13385                 error "Short read filed: read $NOB bytes instead of 1572864"
13386         fi
13387         rm -f $DIR/$tfile
13388 }
13389 run_test 131d "test short read"
13390
13391 test_131e() {
13392         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13393         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13394         error "read hitting hole failed"
13395         rm -f $DIR/$tfile
13396 }
13397 run_test 131e "test read hitting hole"
13398
13399 check_stats() {
13400         local facet=$1
13401         local op=$2
13402         local want=${3:-0}
13403         local res
13404
13405         case $facet in
13406         mds*) res=$(do_facet $facet \
13407                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13408                  ;;
13409         ost*) res=$(do_facet $facet \
13410                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13411                  ;;
13412         *) error "Wrong facet '$facet'" ;;
13413         esac
13414         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13415         # if the argument $3 is zero, it means any stat increment is ok.
13416         if [[ $want -gt 0 ]]; then
13417                 local count=$(echo $res | awk '{ print $2 }')
13418                 [[ $count -ne $want ]] &&
13419                         error "The $op counter on $facet is $count, not $want"
13420         fi
13421 }
13422
13423 test_133a() {
13424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13425         remote_ost_nodsh && skip "remote OST with nodsh"
13426         remote_mds_nodsh && skip "remote MDS with nodsh"
13427         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13428                 skip_env "MDS doesn't support rename stats"
13429
13430         local testdir=$DIR/${tdir}/stats_testdir
13431
13432         mkdir -p $DIR/${tdir}
13433
13434         # clear stats.
13435         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13436         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13437
13438         # verify mdt stats first.
13439         mkdir ${testdir} || error "mkdir failed"
13440         check_stats $SINGLEMDS "mkdir" 1
13441         touch ${testdir}/${tfile} || error "touch failed"
13442         check_stats $SINGLEMDS "open" 1
13443         check_stats $SINGLEMDS "close" 1
13444         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13445                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13446                 check_stats $SINGLEMDS "mknod" 2
13447         }
13448         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13449         check_stats $SINGLEMDS "unlink" 1
13450         rm -f ${testdir}/${tfile} || error "file remove failed"
13451         check_stats $SINGLEMDS "unlink" 2
13452
13453         # remove working dir and check mdt stats again.
13454         rmdir ${testdir} || error "rmdir failed"
13455         check_stats $SINGLEMDS "rmdir" 1
13456
13457         local testdir1=$DIR/${tdir}/stats_testdir1
13458         mkdir -p ${testdir}
13459         mkdir -p ${testdir1}
13460         touch ${testdir1}/test1
13461         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13462         check_stats $SINGLEMDS "crossdir_rename" 1
13463
13464         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13465         check_stats $SINGLEMDS "samedir_rename" 1
13466
13467         rm -rf $DIR/${tdir}
13468 }
13469 run_test 133a "Verifying MDT stats ========================================"
13470
13471 test_133b() {
13472         local res
13473
13474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13475         remote_ost_nodsh && skip "remote OST with nodsh"
13476         remote_mds_nodsh && skip "remote MDS with nodsh"
13477
13478         local testdir=$DIR/${tdir}/stats_testdir
13479
13480         mkdir -p ${testdir} || error "mkdir failed"
13481         touch ${testdir}/${tfile} || error "touch failed"
13482         cancel_lru_locks mdc
13483
13484         # clear stats.
13485         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13486         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13487
13488         # extra mdt stats verification.
13489         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13490         check_stats $SINGLEMDS "setattr" 1
13491         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13492         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13493         then            # LU-1740
13494                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13495                 check_stats $SINGLEMDS "getattr" 1
13496         fi
13497         rm -rf $DIR/${tdir}
13498
13499         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13500         # so the check below is not reliable
13501         [ $MDSCOUNT -eq 1 ] || return 0
13502
13503         # Sleep to avoid a cached response.
13504         #define OBD_STATFS_CACHE_SECONDS 1
13505         sleep 2
13506         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13507         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13508         $LFS df || error "lfs failed"
13509         check_stats $SINGLEMDS "statfs" 1
13510
13511         # check aggregated statfs (LU-10018)
13512         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13513                 return 0
13514         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13515                 return 0
13516         sleep 2
13517         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13518         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13519         df $DIR
13520         check_stats $SINGLEMDS "statfs" 1
13521
13522         # We want to check that the client didn't send OST_STATFS to
13523         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13524         # extra care is needed here.
13525         if remote_mds; then
13526                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13527                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13528
13529                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13530                 [ "$res" ] && error "OST got STATFS"
13531         fi
13532
13533         return 0
13534 }
13535 run_test 133b "Verifying extra MDT stats =================================="
13536
13537 test_133c() {
13538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13539         remote_ost_nodsh && skip "remote OST with nodsh"
13540         remote_mds_nodsh && skip "remote MDS with nodsh"
13541
13542         local testdir=$DIR/$tdir/stats_testdir
13543
13544         test_mkdir -p $testdir
13545
13546         # verify obdfilter stats.
13547         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13548         sync
13549         cancel_lru_locks osc
13550         wait_delete_completed
13551
13552         # clear stats.
13553         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13554         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13555
13556         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13557                 error "dd failed"
13558         sync
13559         cancel_lru_locks osc
13560         check_stats ost1 "write" 1
13561
13562         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13563         check_stats ost1 "read" 1
13564
13565         > $testdir/$tfile || error "truncate failed"
13566         check_stats ost1 "punch" 1
13567
13568         rm -f $testdir/$tfile || error "file remove failed"
13569         wait_delete_completed
13570         check_stats ost1 "destroy" 1
13571
13572         rm -rf $DIR/$tdir
13573 }
13574 run_test 133c "Verifying OST stats ========================================"
13575
13576 order_2() {
13577         local value=$1
13578         local orig=$value
13579         local order=1
13580
13581         while [ $value -ge 2 ]; do
13582                 order=$((order*2))
13583                 value=$((value/2))
13584         done
13585
13586         if [ $orig -gt $order ]; then
13587                 order=$((order*2))
13588         fi
13589         echo $order
13590 }
13591
13592 size_in_KMGT() {
13593     local value=$1
13594     local size=('K' 'M' 'G' 'T');
13595     local i=0
13596     local size_string=$value
13597
13598     while [ $value -ge 1024 ]; do
13599         if [ $i -gt 3 ]; then
13600             #T is the biggest unit we get here, if that is bigger,
13601             #just return XXXT
13602             size_string=${value}T
13603             break
13604         fi
13605         value=$((value >> 10))
13606         if [ $value -lt 1024 ]; then
13607             size_string=${value}${size[$i]}
13608             break
13609         fi
13610         i=$((i + 1))
13611     done
13612
13613     echo $size_string
13614 }
13615
13616 get_rename_size() {
13617         local size=$1
13618         local context=${2:-.}
13619         local sample=$(do_facet $SINGLEMDS $LCTL \
13620                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13621                 grep -A1 $context |
13622                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13623         echo $sample
13624 }
13625
13626 test_133d() {
13627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13628         remote_ost_nodsh && skip "remote OST with nodsh"
13629         remote_mds_nodsh && skip "remote MDS with nodsh"
13630         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13631                 skip_env "MDS doesn't support rename stats"
13632
13633         local testdir1=$DIR/${tdir}/stats_testdir1
13634         local testdir2=$DIR/${tdir}/stats_testdir2
13635         mkdir -p $DIR/${tdir}
13636
13637         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13638
13639         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13640         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13641
13642         createmany -o $testdir1/test 512 || error "createmany failed"
13643
13644         # check samedir rename size
13645         mv ${testdir1}/test0 ${testdir1}/test_0
13646
13647         local testdir1_size=$(ls -l $DIR/${tdir} |
13648                 awk '/stats_testdir1/ {print $5}')
13649         local testdir2_size=$(ls -l $DIR/${tdir} |
13650                 awk '/stats_testdir2/ {print $5}')
13651
13652         testdir1_size=$(order_2 $testdir1_size)
13653         testdir2_size=$(order_2 $testdir2_size)
13654
13655         testdir1_size=$(size_in_KMGT $testdir1_size)
13656         testdir2_size=$(size_in_KMGT $testdir2_size)
13657
13658         echo "source rename dir size: ${testdir1_size}"
13659         echo "target rename dir size: ${testdir2_size}"
13660
13661         local cmd="do_facet $SINGLEMDS $LCTL "
13662         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13663
13664         eval $cmd || error "$cmd failed"
13665         local samedir=$($cmd | grep 'same_dir')
13666         local same_sample=$(get_rename_size $testdir1_size)
13667         [ -z "$samedir" ] && error "samedir_rename_size count error"
13668         [[ $same_sample -eq 1 ]] ||
13669                 error "samedir_rename_size error $same_sample"
13670         echo "Check same dir rename stats success"
13671
13672         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13673
13674         # check crossdir rename size
13675         mv ${testdir1}/test_0 ${testdir2}/test_0
13676
13677         testdir1_size=$(ls -l $DIR/${tdir} |
13678                 awk '/stats_testdir1/ {print $5}')
13679         testdir2_size=$(ls -l $DIR/${tdir} |
13680                 awk '/stats_testdir2/ {print $5}')
13681
13682         testdir1_size=$(order_2 $testdir1_size)
13683         testdir2_size=$(order_2 $testdir2_size)
13684
13685         testdir1_size=$(size_in_KMGT $testdir1_size)
13686         testdir2_size=$(size_in_KMGT $testdir2_size)
13687
13688         echo "source rename dir size: ${testdir1_size}"
13689         echo "target rename dir size: ${testdir2_size}"
13690
13691         eval $cmd || error "$cmd failed"
13692         local crossdir=$($cmd | grep 'crossdir')
13693         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13694         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13695         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13696         [[ $src_sample -eq 1 ]] ||
13697                 error "crossdir_rename_size error $src_sample"
13698         [[ $tgt_sample -eq 1 ]] ||
13699                 error "crossdir_rename_size error $tgt_sample"
13700         echo "Check cross dir rename stats success"
13701         rm -rf $DIR/${tdir}
13702 }
13703 run_test 133d "Verifying rename_stats ========================================"
13704
13705 test_133e() {
13706         remote_mds_nodsh && skip "remote MDS with nodsh"
13707         remote_ost_nodsh && skip "remote OST with nodsh"
13708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13709
13710         local testdir=$DIR/${tdir}/stats_testdir
13711         local ctr f0 f1 bs=32768 count=42 sum
13712
13713         mkdir -p ${testdir} || error "mkdir failed"
13714
13715         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13716
13717         for ctr in {write,read}_bytes; do
13718                 sync
13719                 cancel_lru_locks osc
13720
13721                 do_facet ost1 $LCTL set_param -n \
13722                         "obdfilter.*.exports.clear=clear"
13723
13724                 if [ $ctr = write_bytes ]; then
13725                         f0=/dev/zero
13726                         f1=${testdir}/${tfile}
13727                 else
13728                         f0=${testdir}/${tfile}
13729                         f1=/dev/null
13730                 fi
13731
13732                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13733                         error "dd failed"
13734                 sync
13735                 cancel_lru_locks osc
13736
13737                 sum=$(do_facet ost1 $LCTL get_param \
13738                         "obdfilter.*.exports.*.stats" |
13739                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13740                                 $1 == ctr { sum += $7 }
13741                                 END { printf("%0.0f", sum) }')
13742
13743                 if ((sum != bs * count)); then
13744                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13745                 fi
13746         done
13747
13748         rm -rf $DIR/${tdir}
13749 }
13750 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13751
13752 test_133f() {
13753         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13754                 skip "too old lustre for get_param -R ($facet_ver)"
13755
13756         # verifying readability.
13757         $LCTL get_param -R '*' &> /dev/null
13758
13759         # Verifing writability with badarea_io.
13760         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13761                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13762                 error "client badarea_io failed"
13763
13764         # remount the FS in case writes/reads /proc break the FS
13765         cleanup || error "failed to unmount"
13766         setup || error "failed to setup"
13767 }
13768 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13769
13770 test_133g() {
13771         remote_mds_nodsh && skip "remote MDS with nodsh"
13772         remote_ost_nodsh && skip "remote OST with nodsh"
13773
13774         local facet
13775         for facet in mds1 ost1; do
13776                 local facet_ver=$(lustre_version_code $facet)
13777                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13778                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13779                 else
13780                         log "$facet: too old lustre for get_param -R"
13781                 fi
13782                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13783                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13784                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13785                                 xargs badarea_io" ||
13786                                         error "$facet badarea_io failed"
13787                 else
13788                         skip_noexit "$facet: too old lustre for get_param -R"
13789                 fi
13790         done
13791
13792         # remount the FS in case writes/reads /proc break the FS
13793         cleanup || error "failed to unmount"
13794         setup || error "failed to setup"
13795 }
13796 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13797
13798 test_133h() {
13799         remote_mds_nodsh && skip "remote MDS with nodsh"
13800         remote_ost_nodsh && skip "remote OST with nodsh"
13801         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13802                 skip "Need MDS version at least 2.9.54"
13803
13804         local facet
13805         for facet in client mds1 ost1; do
13806                 # Get the list of files that are missing the terminating newline
13807                 local plist=$(do_facet $facet
13808                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13809                 local ent
13810                 for ent in $plist; do
13811                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13812                                 awk -v FS='\v' -v RS='\v\v' \
13813                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13814                                         print FILENAME}'" 2>/dev/null)
13815                         [ -z $missing ] || {
13816                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13817                                 error "file does not end with newline: $facet-$ent"
13818                         }
13819                 done
13820         done
13821 }
13822 run_test 133h "Proc files should end with newlines"
13823
13824 test_134a() {
13825         remote_mds_nodsh && skip "remote MDS with nodsh"
13826         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13827                 skip "Need MDS version at least 2.7.54"
13828
13829         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13830         cancel_lru_locks mdc
13831
13832         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13833         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13834         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13835
13836         local nr=1000
13837         createmany -o $DIR/$tdir/f $nr ||
13838                 error "failed to create $nr files in $DIR/$tdir"
13839         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13840
13841         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13842         do_facet mds1 $LCTL set_param fail_loc=0x327
13843         do_facet mds1 $LCTL set_param fail_val=500
13844         touch $DIR/$tdir/m
13845
13846         echo "sleep 10 seconds ..."
13847         sleep 10
13848         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13849
13850         do_facet mds1 $LCTL set_param fail_loc=0
13851         do_facet mds1 $LCTL set_param fail_val=0
13852         [ $lck_cnt -lt $unused ] ||
13853                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13854
13855         rm $DIR/$tdir/m
13856         unlinkmany $DIR/$tdir/f $nr
13857 }
13858 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13859
13860 test_134b() {
13861         remote_mds_nodsh && skip "remote MDS with nodsh"
13862         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13863                 skip "Need MDS version at least 2.7.54"
13864
13865         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13866         cancel_lru_locks mdc
13867
13868         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13869                         ldlm.lock_reclaim_threshold_mb)
13870         # disable reclaim temporarily
13871         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13872
13873         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13874         do_facet mds1 $LCTL set_param fail_loc=0x328
13875         do_facet mds1 $LCTL set_param fail_val=500
13876
13877         $LCTL set_param debug=+trace
13878
13879         local nr=600
13880         createmany -o $DIR/$tdir/f $nr &
13881         local create_pid=$!
13882
13883         echo "Sleep $TIMEOUT seconds ..."
13884         sleep $TIMEOUT
13885         if ! ps -p $create_pid  > /dev/null 2>&1; then
13886                 do_facet mds1 $LCTL set_param fail_loc=0
13887                 do_facet mds1 $LCTL set_param fail_val=0
13888                 do_facet mds1 $LCTL set_param \
13889                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13890                 error "createmany finished incorrectly!"
13891         fi
13892         do_facet mds1 $LCTL set_param fail_loc=0
13893         do_facet mds1 $LCTL set_param fail_val=0
13894         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13895         wait $create_pid || return 1
13896
13897         unlinkmany $DIR/$tdir/f $nr
13898 }
13899 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13900
13901 test_135() {
13902         remote_mds_nodsh && skip "remote MDS with nodsh"
13903         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13904                 skip "Need MDS version at least 2.13.50"
13905         local fname
13906
13907         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13908
13909 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13910         #set only one record at plain llog
13911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13912
13913         #fill already existed plain llog each 64767
13914         #wrapping whole catalog
13915         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13916
13917         createmany -o $DIR/$tdir/$tfile_ 64700
13918         for (( i = 0; i < 64700; i = i + 2 ))
13919         do
13920                 rm $DIR/$tdir/$tfile_$i &
13921                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13922                 local pid=$!
13923                 wait $pid
13924         done
13925
13926         #waiting osp synchronization
13927         wait_delete_completed
13928 }
13929 run_test 135 "Race catalog processing"
13930
13931 test_136() {
13932         remote_mds_nodsh && skip "remote MDS with nodsh"
13933         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13934                 skip "Need MDS version at least 2.13.50"
13935         local fname
13936
13937         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13938         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13939         #set only one record at plain llog
13940 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13941         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13942
13943         #fill already existed 2 plain llogs each 64767
13944         #wrapping whole catalog
13945         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13946         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13947         wait_delete_completed
13948
13949         createmany -o $DIR/$tdir/$tfile_ 10
13950         sleep 25
13951
13952         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13953         for (( i = 0; i < 10; i = i + 3 ))
13954         do
13955                 rm $DIR/$tdir/$tfile_$i &
13956                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13957                 local pid=$!
13958                 wait $pid
13959                 sleep 7
13960                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13961         done
13962
13963         #waiting osp synchronization
13964         wait_delete_completed
13965 }
13966 run_test 136 "Race catalog processing 2"
13967
13968 test_140() { #bug-17379
13969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13970
13971         test_mkdir $DIR/$tdir
13972         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13973         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13974
13975         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13976         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13977         local i=0
13978         while i=$((i + 1)); do
13979                 test_mkdir $i
13980                 cd $i || error "Changing to $i"
13981                 ln -s ../stat stat || error "Creating stat symlink"
13982                 # Read the symlink until ELOOP present,
13983                 # not LBUGing the system is considered success,
13984                 # we didn't overrun the stack.
13985                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13986                 if [ $ret -ne 0 ]; then
13987                         if [ $ret -eq 40 ]; then
13988                                 break  # -ELOOP
13989                         else
13990                                 error "Open stat symlink"
13991                                         return
13992                         fi
13993                 fi
13994         done
13995         i=$((i - 1))
13996         echo "The symlink depth = $i"
13997         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13998                 error "Invalid symlink depth"
13999
14000         # Test recursive symlink
14001         ln -s symlink_self symlink_self
14002         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14003         echo "open symlink_self returns $ret"
14004         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14005 }
14006 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14007
14008 test_150a() {
14009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14010
14011         local TF="$TMP/$tfile"
14012
14013         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14014         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14015         cp $TF $DIR/$tfile
14016         cancel_lru_locks $OSC
14017         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14018         remount_client $MOUNT
14019         df -P $MOUNT
14020         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14021
14022         $TRUNCATE $TF 6000
14023         $TRUNCATE $DIR/$tfile 6000
14024         cancel_lru_locks $OSC
14025         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14026
14027         echo "12345" >>$TF
14028         echo "12345" >>$DIR/$tfile
14029         cancel_lru_locks $OSC
14030         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14031
14032         echo "12345" >>$TF
14033         echo "12345" >>$DIR/$tfile
14034         cancel_lru_locks $OSC
14035         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14036 }
14037 run_test 150a "truncate/append tests"
14038
14039 test_150b() {
14040         check_set_fallocate_or_skip
14041
14042         touch $DIR/$tfile
14043         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14044         check_fallocate $DIR/$tfile || error "fallocate failed"
14045 }
14046 run_test 150b "Verify fallocate (prealloc) functionality"
14047
14048 test_150bb() {
14049         check_set_fallocate_or_skip
14050
14051         touch $DIR/$tfile
14052         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14053         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14054         > $DIR/$tfile
14055         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14056         # precomputed md5sum for 20MB of zeroes
14057         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14058         local sum=($(md5sum $DIR/$tfile))
14059
14060         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14061
14062         check_set_fallocate 1
14063
14064         > $DIR/$tfile
14065         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14066         sum=($(md5sum $DIR/$tfile))
14067
14068         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14069 }
14070 run_test 150bb "Verify fallocate modes both zero space"
14071
14072 test_150c() {
14073         check_set_fallocate_or_skip
14074
14075         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14076         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14077         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14078         sync; sync_all_data
14079         cancel_lru_locks $OSC
14080         sleep 5
14081         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14082         want=$((OSTCOUNT * 1048576))
14083
14084         # Must allocate all requested space, not more than 5% extra
14085         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14086                 error "bytes $bytes is not $want"
14087
14088         rm -f $DIR/$tfile
14089         # verify fallocate on PFL file
14090         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14091                 error "Create $DIR/$tfile failed"
14092         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14093                         error "fallocate failed"
14094         sync; sync_all_data
14095         cancel_lru_locks $OSC
14096         sleep 5
14097         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14098         local want=$((1024 * 1048576))
14099
14100         # Must allocate all requested space, not more than 5% extra
14101         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14102                 error "bytes $bytes is not $want"
14103 }
14104 run_test 150c "Verify fallocate Size and Blocks"
14105
14106 test_150d() {
14107         check_set_fallocate_or_skip
14108
14109         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14110         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14111         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14112         sync; sync_all_data
14113         cancel_lru_locks $OSC
14114         sleep 5
14115         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14116         local want=$((OSTCOUNT * 1048576))
14117
14118         # Must allocate all requested space, not more than 5% extra
14119         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14120                 error "bytes $bytes is not $want"
14121 }
14122 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14123
14124 test_150e() {
14125         check_set_fallocate_or_skip
14126
14127         echo "df before:"
14128         $LFS df
14129         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14130         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14131                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14132
14133         # Find OST with Minimum Size
14134         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14135                        sort -un | head -1)
14136
14137         # Get 100MB per OST of the available space to reduce run time
14138         # else 60% of the available space if we are running SLOW tests
14139         if [ $SLOW == "no" ]; then
14140                 local space=$((1024 * 100 * OSTCOUNT))
14141         else
14142                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14143         fi
14144
14145         fallocate -l${space}k $DIR/$tfile ||
14146                 error "fallocate ${space}k $DIR/$tfile failed"
14147         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14148
14149         # get size immediately after fallocate. This should be correctly
14150         # updated
14151         local size=$(stat -c '%s' $DIR/$tfile)
14152         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14153
14154         # Sleep for a while for statfs to get updated. And not pull from cache.
14155         sleep 2
14156
14157         echo "df after fallocate:"
14158         $LFS df
14159
14160         (( size / 1024 == space )) || error "size $size != requested $space"
14161         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14162                 error "used $used < space $space"
14163
14164         rm $DIR/$tfile || error "rm failed"
14165         sync
14166         wait_delete_completed
14167
14168         echo "df after unlink:"
14169         $LFS df
14170 }
14171 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14172
14173 test_150f() {
14174         local size
14175         local blocks
14176         local want_size_before=20480 # in bytes
14177         local want_blocks_before=40 # 512 sized blocks
14178         local want_blocks_after=24  # 512 sized blocks
14179         local length=$(((want_blocks_before - want_blocks_after) * 512))
14180
14181         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14182                 skip "need at least 2.14.0 for fallocate punch"
14183
14184         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14185                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14186         fi
14187
14188         check_set_fallocate_or_skip
14189         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14190
14191         echo "Verify fallocate punch: Range within the file range"
14192         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14193                 error "dd failed for bs 4096 and count 5"
14194
14195         # Call fallocate with punch range which is within the file range
14196         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14197                 error "fallocate failed: offset 4096 and length $length"
14198         # client must see changes immediately after fallocate
14199         size=$(stat -c '%s' $DIR/$tfile)
14200         blocks=$(stat -c '%b' $DIR/$tfile)
14201
14202         # Verify punch worked.
14203         (( blocks == want_blocks_after )) ||
14204                 error "punch failed: blocks $blocks != $want_blocks_after"
14205
14206         (( size == want_size_before )) ||
14207                 error "punch failed: size $size != $want_size_before"
14208
14209         # Verify there is hole in file
14210         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14211         # precomputed md5sum
14212         local expect="4a9a834a2db02452929c0a348273b4aa"
14213
14214         cksum=($(md5sum $DIR/$tfile))
14215         [[ "${cksum[0]}" == "$expect" ]] ||
14216                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14217
14218         # Start second sub-case for fallocate punch.
14219         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14220         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14221                 error "dd failed for bs 4096 and count 5"
14222
14223         # Punch range less than block size will have no change in block count
14224         want_blocks_after=40  # 512 sized blocks
14225
14226         # Punch overlaps two blocks and less than blocksize
14227         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14228                 error "fallocate failed: offset 4000 length 3000"
14229         size=$(stat -c '%s' $DIR/$tfile)
14230         blocks=$(stat -c '%b' $DIR/$tfile)
14231
14232         # Verify punch worked.
14233         (( blocks == want_blocks_after )) ||
14234                 error "punch failed: blocks $blocks != $want_blocks_after"
14235
14236         (( size == want_size_before )) ||
14237                 error "punch failed: size $size != $want_size_before"
14238
14239         # Verify if range is really zero'ed out. We expect Zeros.
14240         # precomputed md5sum
14241         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14242         cksum=($(md5sum $DIR/$tfile))
14243         [[ "${cksum[0]}" == "$expect" ]] ||
14244                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14245 }
14246 run_test 150f "Verify fallocate punch functionality"
14247
14248 test_150g() {
14249         local space
14250         local size
14251         local blocks
14252         local blocks_after
14253         local size_after
14254         local BS=4096 # Block size in bytes
14255
14256         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14257                 skip "need at least 2.14.0 for fallocate punch"
14258
14259         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14260                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14261         fi
14262
14263         check_set_fallocate_or_skip
14264         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14265
14266         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14267                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14268
14269         # Get 100MB per OST of the available space to reduce run time
14270         # else 60% of the available space if we are running SLOW tests
14271         if [ $SLOW == "no" ]; then
14272                 space=$((1024 * 100 * OSTCOUNT))
14273         else
14274                 # Find OST with Minimum Size
14275                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14276                         sort -un | head -1)
14277                 echo "min size OST: $space"
14278                 space=$(((space * 60)/100 * OSTCOUNT))
14279         fi
14280         # space in 1k units, round to 4k blocks
14281         local blkcount=$((space * 1024 / $BS))
14282
14283         echo "Verify fallocate punch: Very large Range"
14284         fallocate -l${space}k $DIR/$tfile ||
14285                 error "fallocate ${space}k $DIR/$tfile failed"
14286         # write 1M at the end, start and in the middle
14287         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14288                 error "dd failed: bs $BS count 256"
14289         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14290                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14291         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14292                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14293
14294         # Gather stats.
14295         size=$(stat -c '%s' $DIR/$tfile)
14296
14297         # gather punch length.
14298         local punch_size=$((size - (BS * 2)))
14299
14300         echo "punch_size = $punch_size"
14301         echo "size - punch_size: $((size - punch_size))"
14302         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14303
14304         # Call fallocate to punch all except 2 blocks. We leave the
14305         # first and the last block
14306         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14307         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14308                 error "fallocate failed: offset $BS length $punch_size"
14309
14310         size_after=$(stat -c '%s' $DIR/$tfile)
14311         blocks_after=$(stat -c '%b' $DIR/$tfile)
14312
14313         # Verify punch worked.
14314         # Size should be kept
14315         (( size == size_after )) ||
14316                 error "punch failed: size $size != $size_after"
14317
14318         # two 4k data blocks to remain plus possible 1 extra extent block
14319         (( blocks_after <= ((BS / 512) * 3) )) ||
14320                 error "too many blocks remains: $blocks_after"
14321
14322         # Verify that file has hole between the first and the last blocks
14323         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14324         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14325
14326         echo "Hole at [$hole_start, $hole_end)"
14327         (( hole_start == BS )) ||
14328                 error "no hole at offset $BS after punch"
14329
14330         (( hole_end == BS + punch_size )) ||
14331                 error "data at offset $hole_end < $((BS + punch_size))"
14332 }
14333 run_test 150g "Verify fallocate punch on large range"
14334
14335 #LU-2902 roc_hit was not able to read all values from lproc
14336 function roc_hit_init() {
14337         local list=$(comma_list $(osts_nodes))
14338         local dir=$DIR/$tdir-check
14339         local file=$dir/$tfile
14340         local BEFORE
14341         local AFTER
14342         local idx
14343
14344         test_mkdir $dir
14345         #use setstripe to do a write to every ost
14346         for i in $(seq 0 $((OSTCOUNT-1))); do
14347                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14348                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14349                 idx=$(printf %04x $i)
14350                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14351                         awk '$1 == "cache_access" {sum += $7}
14352                                 END { printf("%0.0f", sum) }')
14353
14354                 cancel_lru_locks osc
14355                 cat $file >/dev/null
14356
14357                 AFTER=$(get_osd_param $list *OST*$idx stats |
14358                         awk '$1 == "cache_access" {sum += $7}
14359                                 END { printf("%0.0f", sum) }')
14360
14361                 echo BEFORE:$BEFORE AFTER:$AFTER
14362                 if ! let "AFTER - BEFORE == 4"; then
14363                         rm -rf $dir
14364                         error "roc_hit is not safe to use"
14365                 fi
14366                 rm $file
14367         done
14368
14369         rm -rf $dir
14370 }
14371
14372 function roc_hit() {
14373         local list=$(comma_list $(osts_nodes))
14374         echo $(get_osd_param $list '' stats |
14375                 awk '$1 == "cache_hit" {sum += $7}
14376                         END { printf("%0.0f", sum) }')
14377 }
14378
14379 function set_cache() {
14380         local on=1
14381
14382         if [ "$2" == "off" ]; then
14383                 on=0;
14384         fi
14385         local list=$(comma_list $(osts_nodes))
14386         set_osd_param $list '' $1_cache_enable $on
14387
14388         cancel_lru_locks osc
14389 }
14390
14391 test_151() {
14392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14393         remote_ost_nodsh && skip "remote OST with nodsh"
14394
14395         local CPAGES=3
14396         local list=$(comma_list $(osts_nodes))
14397
14398         # check whether obdfilter is cache capable at all
14399         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14400                 skip "not cache-capable obdfilter"
14401         fi
14402
14403         # check cache is enabled on all obdfilters
14404         if get_osd_param $list '' read_cache_enable | grep 0; then
14405                 skip "oss cache is disabled"
14406         fi
14407
14408         set_osd_param $list '' writethrough_cache_enable 1
14409
14410         # check write cache is enabled on all obdfilters
14411         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14412                 skip "oss write cache is NOT enabled"
14413         fi
14414
14415         roc_hit_init
14416
14417         #define OBD_FAIL_OBD_NO_LRU  0x609
14418         do_nodes $list $LCTL set_param fail_loc=0x609
14419
14420         # pages should be in the case right after write
14421         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14422                 error "dd failed"
14423
14424         local BEFORE=$(roc_hit)
14425         cancel_lru_locks osc
14426         cat $DIR/$tfile >/dev/null
14427         local AFTER=$(roc_hit)
14428
14429         do_nodes $list $LCTL set_param fail_loc=0
14430
14431         if ! let "AFTER - BEFORE == CPAGES"; then
14432                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14433         fi
14434
14435         cancel_lru_locks osc
14436         # invalidates OST cache
14437         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14438         set_osd_param $list '' read_cache_enable 0
14439         cat $DIR/$tfile >/dev/null
14440
14441         # now data shouldn't be found in the cache
14442         BEFORE=$(roc_hit)
14443         cancel_lru_locks osc
14444         cat $DIR/$tfile >/dev/null
14445         AFTER=$(roc_hit)
14446         if let "AFTER - BEFORE != 0"; then
14447                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14448         fi
14449
14450         set_osd_param $list '' read_cache_enable 1
14451         rm -f $DIR/$tfile
14452 }
14453 run_test 151 "test cache on oss and controls ==============================="
14454
14455 test_152() {
14456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14457
14458         local TF="$TMP/$tfile"
14459
14460         # simulate ENOMEM during write
14461 #define OBD_FAIL_OST_NOMEM      0x226
14462         lctl set_param fail_loc=0x80000226
14463         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14464         cp $TF $DIR/$tfile
14465         sync || error "sync failed"
14466         lctl set_param fail_loc=0
14467
14468         # discard client's cache
14469         cancel_lru_locks osc
14470
14471         # simulate ENOMEM during read
14472         lctl set_param fail_loc=0x80000226
14473         cmp $TF $DIR/$tfile || error "cmp failed"
14474         lctl set_param fail_loc=0
14475
14476         rm -f $TF
14477 }
14478 run_test 152 "test read/write with enomem ============================"
14479
14480 test_153() {
14481         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14482 }
14483 run_test 153 "test if fdatasync does not crash ======================="
14484
14485 dot_lustre_fid_permission_check() {
14486         local fid=$1
14487         local ffid=$MOUNT/.lustre/fid/$fid
14488         local test_dir=$2
14489
14490         echo "stat fid $fid"
14491         stat $ffid > /dev/null || error "stat $ffid failed."
14492         echo "touch fid $fid"
14493         touch $ffid || error "touch $ffid failed."
14494         echo "write to fid $fid"
14495         cat /etc/hosts > $ffid || error "write $ffid failed."
14496         echo "read fid $fid"
14497         diff /etc/hosts $ffid || error "read $ffid failed."
14498         echo "append write to fid $fid"
14499         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14500         echo "rename fid $fid"
14501         mv $ffid $test_dir/$tfile.1 &&
14502                 error "rename $ffid to $tfile.1 should fail."
14503         touch $test_dir/$tfile.1
14504         mv $test_dir/$tfile.1 $ffid &&
14505                 error "rename $tfile.1 to $ffid should fail."
14506         rm -f $test_dir/$tfile.1
14507         echo "truncate fid $fid"
14508         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14509         echo "link fid $fid"
14510         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14511         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14512                 echo "setfacl fid $fid"
14513                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14514                 echo "getfacl fid $fid"
14515                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14516         fi
14517         echo "unlink fid $fid"
14518         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14519         echo "mknod fid $fid"
14520         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14521
14522         fid=[0xf00000400:0x1:0x0]
14523         ffid=$MOUNT/.lustre/fid/$fid
14524
14525         echo "stat non-exist fid $fid"
14526         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14527         echo "write to non-exist fid $fid"
14528         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14529         echo "link new fid $fid"
14530         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14531
14532         mkdir -p $test_dir/$tdir
14533         touch $test_dir/$tdir/$tfile
14534         fid=$($LFS path2fid $test_dir/$tdir)
14535         rc=$?
14536         [ $rc -ne 0 ] &&
14537                 error "error: could not get fid for $test_dir/$dir/$tfile."
14538
14539         ffid=$MOUNT/.lustre/fid/$fid
14540
14541         echo "ls $fid"
14542         ls $ffid > /dev/null || error "ls $ffid failed."
14543         echo "touch $fid/$tfile.1"
14544         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14545
14546         echo "touch $MOUNT/.lustre/fid/$tfile"
14547         touch $MOUNT/.lustre/fid/$tfile && \
14548                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14549
14550         echo "setxattr to $MOUNT/.lustre/fid"
14551         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14552
14553         echo "listxattr for $MOUNT/.lustre/fid"
14554         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14555
14556         echo "delxattr from $MOUNT/.lustre/fid"
14557         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14558
14559         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14560         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14561                 error "touch invalid fid should fail."
14562
14563         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14564         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14565                 error "touch non-normal fid should fail."
14566
14567         echo "rename $tdir to $MOUNT/.lustre/fid"
14568         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14569                 error "rename to $MOUNT/.lustre/fid should fail."
14570
14571         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14572         then            # LU-3547
14573                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14574                 local new_obf_mode=777
14575
14576                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14577                 chmod $new_obf_mode $DIR/.lustre/fid ||
14578                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14579
14580                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14581                 [ $obf_mode -eq $new_obf_mode ] ||
14582                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14583
14584                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14585                 chmod $old_obf_mode $DIR/.lustre/fid ||
14586                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14587         fi
14588
14589         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14590         fid=$($LFS path2fid $test_dir/$tfile-2)
14591
14592         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14593         then # LU-5424
14594                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14595                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14596                         error "create lov data thru .lustre failed"
14597         fi
14598         echo "cp /etc/passwd $test_dir/$tfile-2"
14599         cp /etc/passwd $test_dir/$tfile-2 ||
14600                 error "copy to $test_dir/$tfile-2 failed."
14601         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14602         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14603                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14604
14605         rm -rf $test_dir/tfile.lnk
14606         rm -rf $test_dir/$tfile-2
14607 }
14608
14609 test_154A() {
14610         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14611                 skip "Need MDS version at least 2.4.1"
14612
14613         local tf=$DIR/$tfile
14614         touch $tf
14615
14616         local fid=$($LFS path2fid $tf)
14617         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14618
14619         # check that we get the same pathname back
14620         local rootpath
14621         local found
14622         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14623                 echo "$rootpath $fid"
14624                 found=$($LFS fid2path $rootpath "$fid")
14625                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14626                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14627         done
14628
14629         # check wrong root path format
14630         rootpath=$MOUNT"_wrong"
14631         found=$($LFS fid2path $rootpath "$fid")
14632         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14633 }
14634 run_test 154A "lfs path2fid and fid2path basic checks"
14635
14636 test_154B() {
14637         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14638                 skip "Need MDS version at least 2.4.1"
14639
14640         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14641         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14642         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14643         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14644
14645         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14646         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14647
14648         # check that we get the same pathname
14649         echo "PFID: $PFID, name: $name"
14650         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14651         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14652         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14653                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14654
14655         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14656 }
14657 run_test 154B "verify the ll_decode_linkea tool"
14658
14659 test_154a() {
14660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14661         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14662         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14663                 skip "Need MDS version at least 2.2.51"
14664         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14665
14666         cp /etc/hosts $DIR/$tfile
14667
14668         fid=$($LFS path2fid $DIR/$tfile)
14669         rc=$?
14670         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14671
14672         dot_lustre_fid_permission_check "$fid" $DIR ||
14673                 error "dot lustre permission check $fid failed"
14674
14675         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14676
14677         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14678
14679         touch $MOUNT/.lustre/file &&
14680                 error "creation is not allowed under .lustre"
14681
14682         mkdir $MOUNT/.lustre/dir &&
14683                 error "mkdir is not allowed under .lustre"
14684
14685         rm -rf $DIR/$tfile
14686 }
14687 run_test 154a "Open-by-FID"
14688
14689 test_154b() {
14690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14691         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14692         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14693         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14694                 skip "Need MDS version at least 2.2.51"
14695
14696         local remote_dir=$DIR/$tdir/remote_dir
14697         local MDTIDX=1
14698         local rc=0
14699
14700         mkdir -p $DIR/$tdir
14701         $LFS mkdir -i $MDTIDX $remote_dir ||
14702                 error "create remote directory failed"
14703
14704         cp /etc/hosts $remote_dir/$tfile
14705
14706         fid=$($LFS path2fid $remote_dir/$tfile)
14707         rc=$?
14708         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14709
14710         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14711                 error "dot lustre permission check $fid failed"
14712         rm -rf $DIR/$tdir
14713 }
14714 run_test 154b "Open-by-FID for remote directory"
14715
14716 test_154c() {
14717         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14718                 skip "Need MDS version at least 2.4.1"
14719
14720         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14721         local FID1=$($LFS path2fid $DIR/$tfile.1)
14722         local FID2=$($LFS path2fid $DIR/$tfile.2)
14723         local FID3=$($LFS path2fid $DIR/$tfile.3)
14724
14725         local N=1
14726         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14727                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14728                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14729                 local want=FID$N
14730                 [ "$FID" = "${!want}" ] ||
14731                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14732                 N=$((N + 1))
14733         done
14734
14735         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14736         do
14737                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14738                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14739                 N=$((N + 1))
14740         done
14741 }
14742 run_test 154c "lfs path2fid and fid2path multiple arguments"
14743
14744 test_154d() {
14745         remote_mds_nodsh && skip "remote MDS with nodsh"
14746         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14747                 skip "Need MDS version at least 2.5.53"
14748
14749         if remote_mds; then
14750                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14751         else
14752                 nid="0@lo"
14753         fi
14754         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14755         local fd
14756         local cmd
14757
14758         rm -f $DIR/$tfile
14759         touch $DIR/$tfile
14760
14761         local fid=$($LFS path2fid $DIR/$tfile)
14762         # Open the file
14763         fd=$(free_fd)
14764         cmd="exec $fd<$DIR/$tfile"
14765         eval $cmd
14766         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14767         echo "$fid_list" | grep "$fid"
14768         rc=$?
14769
14770         cmd="exec $fd>/dev/null"
14771         eval $cmd
14772         if [ $rc -ne 0 ]; then
14773                 error "FID $fid not found in open files list $fid_list"
14774         fi
14775 }
14776 run_test 154d "Verify open file fid"
14777
14778 test_154e()
14779 {
14780         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14781                 skip "Need MDS version at least 2.6.50"
14782
14783         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14784                 error ".lustre returned by readdir"
14785         fi
14786 }
14787 run_test 154e ".lustre is not returned by readdir"
14788
14789 test_154f() {
14790         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14791
14792         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14793         test_mkdir -p -c1 $DIR/$tdir/d
14794         # test dirs inherit from its stripe
14795         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14796         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14797         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14798         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14799         touch $DIR/f
14800
14801         # get fid of parents
14802         local FID0=$($LFS path2fid $DIR/$tdir/d)
14803         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14804         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14805         local FID3=$($LFS path2fid $DIR)
14806
14807         # check that path2fid --parents returns expected <parent_fid>/name
14808         # 1) test for a directory (single parent)
14809         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14810         [ "$parent" == "$FID0/foo1" ] ||
14811                 error "expected parent: $FID0/foo1, got: $parent"
14812
14813         # 2) test for a file with nlink > 1 (multiple parents)
14814         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14815         echo "$parent" | grep -F "$FID1/$tfile" ||
14816                 error "$FID1/$tfile not returned in parent list"
14817         echo "$parent" | grep -F "$FID2/link" ||
14818                 error "$FID2/link not returned in parent list"
14819
14820         # 3) get parent by fid
14821         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14822         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14823         echo "$parent" | grep -F "$FID1/$tfile" ||
14824                 error "$FID1/$tfile not returned in parent list (by fid)"
14825         echo "$parent" | grep -F "$FID2/link" ||
14826                 error "$FID2/link not returned in parent list (by fid)"
14827
14828         # 4) test for entry in root directory
14829         parent=$($LFS path2fid --parents $DIR/f)
14830         echo "$parent" | grep -F "$FID3/f" ||
14831                 error "$FID3/f not returned in parent list"
14832
14833         # 5) test it on root directory
14834         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14835                 error "$MOUNT should not have parents"
14836
14837         # enable xattr caching and check that linkea is correctly updated
14838         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14839         save_lustre_params client "llite.*.xattr_cache" > $save
14840         lctl set_param llite.*.xattr_cache 1
14841
14842         # 6.1) linkea update on rename
14843         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14844
14845         # get parents by fid
14846         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14847         # foo1 should no longer be returned in parent list
14848         echo "$parent" | grep -F "$FID1" &&
14849                 error "$FID1 should no longer be in parent list"
14850         # the new path should appear
14851         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14852                 error "$FID2/$tfile.moved is not in parent list"
14853
14854         # 6.2) linkea update on unlink
14855         rm -f $DIR/$tdir/d/foo2/link
14856         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14857         # foo2/link should no longer be returned in parent list
14858         echo "$parent" | grep -F "$FID2/link" &&
14859                 error "$FID2/link should no longer be in parent list"
14860         true
14861
14862         rm -f $DIR/f
14863         restore_lustre_params < $save
14864         rm -f $save
14865 }
14866 run_test 154f "get parent fids by reading link ea"
14867
14868 test_154g()
14869 {
14870         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14871         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14872            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14873                 skip "Need MDS version at least 2.6.92"
14874
14875         mkdir -p $DIR/$tdir
14876         llapi_fid_test -d $DIR/$tdir
14877 }
14878 run_test 154g "various llapi FID tests"
14879
14880 test_155_small_load() {
14881     local temp=$TMP/$tfile
14882     local file=$DIR/$tfile
14883
14884     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14885         error "dd of=$temp bs=6096 count=1 failed"
14886     cp $temp $file
14887     cancel_lru_locks $OSC
14888     cmp $temp $file || error "$temp $file differ"
14889
14890     $TRUNCATE $temp 6000
14891     $TRUNCATE $file 6000
14892     cmp $temp $file || error "$temp $file differ (truncate1)"
14893
14894     echo "12345" >>$temp
14895     echo "12345" >>$file
14896     cmp $temp $file || error "$temp $file differ (append1)"
14897
14898     echo "12345" >>$temp
14899     echo "12345" >>$file
14900     cmp $temp $file || error "$temp $file differ (append2)"
14901
14902     rm -f $temp $file
14903     true
14904 }
14905
14906 test_155_big_load() {
14907         remote_ost_nodsh && skip "remote OST with nodsh"
14908
14909         local temp=$TMP/$tfile
14910         local file=$DIR/$tfile
14911
14912         free_min_max
14913         local cache_size=$(do_facet ost$((MAXI+1)) \
14914                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14915         local large_file_size=$((cache_size * 2))
14916
14917         echo "OSS cache size: $cache_size KB"
14918         echo "Large file size: $large_file_size KB"
14919
14920         [ $MAXV -le $large_file_size ] &&
14921                 skip_env "max available OST size needs > $large_file_size KB"
14922
14923         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14924
14925         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14926                 error "dd of=$temp bs=$large_file_size count=1k failed"
14927         cp $temp $file
14928         ls -lh $temp $file
14929         cancel_lru_locks osc
14930         cmp $temp $file || error "$temp $file differ"
14931
14932         rm -f $temp $file
14933         true
14934 }
14935
14936 save_writethrough() {
14937         local facets=$(get_facets OST)
14938
14939         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14940 }
14941
14942 test_155a() {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944
14945         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14946
14947         save_writethrough $p
14948
14949         set_cache read on
14950         set_cache writethrough on
14951         test_155_small_load
14952         restore_lustre_params < $p
14953         rm -f $p
14954 }
14955 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14956
14957 test_155b() {
14958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14959
14960         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14961
14962         save_writethrough $p
14963
14964         set_cache read on
14965         set_cache writethrough off
14966         test_155_small_load
14967         restore_lustre_params < $p
14968         rm -f $p
14969 }
14970 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14971
14972 test_155c() {
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974
14975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14976
14977         save_writethrough $p
14978
14979         set_cache read off
14980         set_cache writethrough on
14981         test_155_small_load
14982         restore_lustre_params < $p
14983         rm -f $p
14984 }
14985 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14986
14987 test_155d() {
14988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14989
14990         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14991
14992         save_writethrough $p
14993
14994         set_cache read off
14995         set_cache writethrough off
14996         test_155_small_load
14997         restore_lustre_params < $p
14998         rm -f $p
14999 }
15000 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15001
15002 test_155e() {
15003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15004
15005         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15006
15007         save_writethrough $p
15008
15009         set_cache read on
15010         set_cache writethrough on
15011         test_155_big_load
15012         restore_lustre_params < $p
15013         rm -f $p
15014 }
15015 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15016
15017 test_155f() {
15018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15019
15020         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15021
15022         save_writethrough $p
15023
15024         set_cache read on
15025         set_cache writethrough off
15026         test_155_big_load
15027         restore_lustre_params < $p
15028         rm -f $p
15029 }
15030 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15031
15032 test_155g() {
15033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15034
15035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15036
15037         save_writethrough $p
15038
15039         set_cache read off
15040         set_cache writethrough on
15041         test_155_big_load
15042         restore_lustre_params < $p
15043         rm -f $p
15044 }
15045 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15046
15047 test_155h() {
15048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15049
15050         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15051
15052         save_writethrough $p
15053
15054         set_cache read off
15055         set_cache writethrough off
15056         test_155_big_load
15057         restore_lustre_params < $p
15058         rm -f $p
15059 }
15060 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15061
15062 test_156() {
15063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15064         remote_ost_nodsh && skip "remote OST with nodsh"
15065         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15066                 skip "stats not implemented on old servers"
15067         [ "$ost1_FSTYPE" = "zfs" ] &&
15068                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15069
15070         local CPAGES=3
15071         local BEFORE
15072         local AFTER
15073         local file="$DIR/$tfile"
15074         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15075
15076         save_writethrough $p
15077         roc_hit_init
15078
15079         log "Turn on read and write cache"
15080         set_cache read on
15081         set_cache writethrough on
15082
15083         log "Write data and read it back."
15084         log "Read should be satisfied from the cache."
15085         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15086         BEFORE=$(roc_hit)
15087         cancel_lru_locks osc
15088         cat $file >/dev/null
15089         AFTER=$(roc_hit)
15090         if ! let "AFTER - BEFORE == CPAGES"; then
15091                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15092         else
15093                 log "cache hits: before: $BEFORE, after: $AFTER"
15094         fi
15095
15096         log "Read again; it should be satisfied from the cache."
15097         BEFORE=$AFTER
15098         cancel_lru_locks osc
15099         cat $file >/dev/null
15100         AFTER=$(roc_hit)
15101         if ! let "AFTER - BEFORE == CPAGES"; then
15102                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15103         else
15104                 log "cache hits:: before: $BEFORE, after: $AFTER"
15105         fi
15106
15107         log "Turn off the read cache and turn on the write cache"
15108         set_cache read off
15109         set_cache writethrough on
15110
15111         log "Read again; it should be satisfied from the cache."
15112         BEFORE=$(roc_hit)
15113         cancel_lru_locks osc
15114         cat $file >/dev/null
15115         AFTER=$(roc_hit)
15116         if ! let "AFTER - BEFORE == CPAGES"; then
15117                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15118         else
15119                 log "cache hits:: before: $BEFORE, after: $AFTER"
15120         fi
15121
15122         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15123                 # > 2.12.56 uses pagecache if cached
15124                 log "Read again; it should not be satisfied from the cache."
15125                 BEFORE=$AFTER
15126                 cancel_lru_locks osc
15127                 cat $file >/dev/null
15128                 AFTER=$(roc_hit)
15129                 if ! let "AFTER - BEFORE == 0"; then
15130                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15131                 else
15132                         log "cache hits:: before: $BEFORE, after: $AFTER"
15133                 fi
15134         fi
15135
15136         log "Write data and read it back."
15137         log "Read should be satisfied from the cache."
15138         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15139         BEFORE=$(roc_hit)
15140         cancel_lru_locks osc
15141         cat $file >/dev/null
15142         AFTER=$(roc_hit)
15143         if ! let "AFTER - BEFORE == CPAGES"; then
15144                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15145         else
15146                 log "cache hits:: before: $BEFORE, after: $AFTER"
15147         fi
15148
15149         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15150                 # > 2.12.56 uses pagecache if cached
15151                 log "Read again; it should not be satisfied from the cache."
15152                 BEFORE=$AFTER
15153                 cancel_lru_locks osc
15154                 cat $file >/dev/null
15155                 AFTER=$(roc_hit)
15156                 if ! let "AFTER - BEFORE == 0"; then
15157                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15158                 else
15159                         log "cache hits:: before: $BEFORE, after: $AFTER"
15160                 fi
15161         fi
15162
15163         log "Turn off read and write cache"
15164         set_cache read off
15165         set_cache writethrough off
15166
15167         log "Write data and read it back"
15168         log "It should not be satisfied from the cache."
15169         rm -f $file
15170         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15171         cancel_lru_locks osc
15172         BEFORE=$(roc_hit)
15173         cat $file >/dev/null
15174         AFTER=$(roc_hit)
15175         if ! let "AFTER - BEFORE == 0"; then
15176                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15177         else
15178                 log "cache hits:: before: $BEFORE, after: $AFTER"
15179         fi
15180
15181         log "Turn on the read cache and turn off the write cache"
15182         set_cache read on
15183         set_cache writethrough off
15184
15185         log "Write data and read it back"
15186         log "It should not be satisfied from the cache."
15187         rm -f $file
15188         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15189         BEFORE=$(roc_hit)
15190         cancel_lru_locks osc
15191         cat $file >/dev/null
15192         AFTER=$(roc_hit)
15193         if ! let "AFTER - BEFORE == 0"; then
15194                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15195         else
15196                 log "cache hits:: before: $BEFORE, after: $AFTER"
15197         fi
15198
15199         log "Read again; it should be satisfied from the cache."
15200         BEFORE=$(roc_hit)
15201         cancel_lru_locks osc
15202         cat $file >/dev/null
15203         AFTER=$(roc_hit)
15204         if ! let "AFTER - BEFORE == CPAGES"; then
15205                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15206         else
15207                 log "cache hits:: before: $BEFORE, after: $AFTER"
15208         fi
15209
15210         restore_lustre_params < $p
15211         rm -f $p $file
15212 }
15213 run_test 156 "Verification of tunables"
15214
15215 test_160a() {
15216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15217         remote_mds_nodsh && skip "remote MDS with nodsh"
15218         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15219                 skip "Need MDS version at least 2.2.0"
15220
15221         changelog_register || error "changelog_register failed"
15222         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15223         changelog_users $SINGLEMDS | grep -q $cl_user ||
15224                 error "User $cl_user not found in changelog_users"
15225
15226         # change something
15227         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15228         changelog_clear 0 || error "changelog_clear failed"
15229         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15230         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15231         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15232         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15233         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15234         rm $DIR/$tdir/pics/desktop.jpg
15235
15236         changelog_dump | tail -10
15237
15238         echo "verifying changelog mask"
15239         changelog_chmask "-MKDIR"
15240         changelog_chmask "-CLOSE"
15241
15242         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15243         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15244
15245         changelog_chmask "+MKDIR"
15246         changelog_chmask "+CLOSE"
15247
15248         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15249         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15250
15251         changelog_dump | tail -10
15252         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15253         CLOSES=$(changelog_dump | grep -c "CLOSE")
15254         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15255         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15256
15257         # verify contents
15258         echo "verifying target fid"
15259         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15260         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15261         [ "$fidc" == "$fidf" ] ||
15262                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15263         echo "verifying parent fid"
15264         # The FID returned from the Changelog may be the directory shard on
15265         # a different MDT, and not the FID returned by path2fid on the parent.
15266         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15267         # since this is what will matter when recreating this file in the tree.
15268         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15269         local pathp=$($LFS fid2path $MOUNT "$fidp")
15270         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15271                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15272
15273         echo "getting records for $cl_user"
15274         changelog_users $SINGLEMDS
15275         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15276         local nclr=3
15277         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15278                 error "changelog_clear failed"
15279         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15280         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15281         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15282                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15283
15284         local min0_rec=$(changelog_users $SINGLEMDS |
15285                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15286         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15287                           awk '{ print $1; exit; }')
15288
15289         changelog_dump | tail -n 5
15290         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15291         [ $first_rec == $((min0_rec + 1)) ] ||
15292                 error "first index should be $min0_rec + 1 not $first_rec"
15293
15294         # LU-3446 changelog index reset on MDT restart
15295         local cur_rec1=$(changelog_users $SINGLEMDS |
15296                          awk '/^current.index:/ { print $NF }')
15297         changelog_clear 0 ||
15298                 error "clear all changelog records for $cl_user failed"
15299         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15300         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15301                 error "Fail to start $SINGLEMDS"
15302         local cur_rec2=$(changelog_users $SINGLEMDS |
15303                          awk '/^current.index:/ { print $NF }')
15304         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15305         [ $cur_rec1 == $cur_rec2 ] ||
15306                 error "current index should be $cur_rec1 not $cur_rec2"
15307
15308         echo "verifying users from this test are deregistered"
15309         changelog_deregister || error "changelog_deregister failed"
15310         changelog_users $SINGLEMDS | grep -q $cl_user &&
15311                 error "User '$cl_user' still in changelog_users"
15312
15313         # lctl get_param -n mdd.*.changelog_users
15314         # current index: 144
15315         # ID    index (idle seconds)
15316         # cl3   144 (2)
15317         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15318                 # this is the normal case where all users were deregistered
15319                 # make sure no new records are added when no users are present
15320                 local last_rec1=$(changelog_users $SINGLEMDS |
15321                                   awk '/^current.index:/ { print $NF }')
15322                 touch $DIR/$tdir/chloe
15323                 local last_rec2=$(changelog_users $SINGLEMDS |
15324                                   awk '/^current.index:/ { print $NF }')
15325                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15326                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15327         else
15328                 # any changelog users must be leftovers from a previous test
15329                 changelog_users $SINGLEMDS
15330                 echo "other changelog users; can't verify off"
15331         fi
15332 }
15333 run_test 160a "changelog sanity"
15334
15335 test_160b() { # LU-3587
15336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15337         remote_mds_nodsh && skip "remote MDS with nodsh"
15338         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15339                 skip "Need MDS version at least 2.2.0"
15340
15341         changelog_register || error "changelog_register failed"
15342         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15343         changelog_users $SINGLEMDS | grep -q $cl_user ||
15344                 error "User '$cl_user' not found in changelog_users"
15345
15346         local longname1=$(str_repeat a 255)
15347         local longname2=$(str_repeat b 255)
15348
15349         cd $DIR
15350         echo "creating very long named file"
15351         touch $longname1 || error "create of '$longname1' failed"
15352         echo "renaming very long named file"
15353         mv $longname1 $longname2
15354
15355         changelog_dump | grep RENME | tail -n 5
15356         rm -f $longname2
15357 }
15358 run_test 160b "Verify that very long rename doesn't crash in changelog"
15359
15360 test_160c() {
15361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15362         remote_mds_nodsh && skip "remote MDS with nodsh"
15363
15364         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15365                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15366                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15367                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15368
15369         local rc=0
15370
15371         # Registration step
15372         changelog_register || error "changelog_register failed"
15373
15374         rm -rf $DIR/$tdir
15375         mkdir -p $DIR/$tdir
15376         $MCREATE $DIR/$tdir/foo_160c
15377         changelog_chmask "-TRUNC"
15378         $TRUNCATE $DIR/$tdir/foo_160c 200
15379         changelog_chmask "+TRUNC"
15380         $TRUNCATE $DIR/$tdir/foo_160c 199
15381         changelog_dump | tail -n 5
15382         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15383         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15384 }
15385 run_test 160c "verify that changelog log catch the truncate event"
15386
15387 test_160d() {
15388         remote_mds_nodsh && skip "remote MDS with nodsh"
15389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15391         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15392                 skip "Need MDS version at least 2.7.60"
15393
15394         # Registration step
15395         changelog_register || error "changelog_register failed"
15396
15397         mkdir -p $DIR/$tdir/migrate_dir
15398         changelog_clear 0 || error "changelog_clear failed"
15399
15400         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15401         changelog_dump | tail -n 5
15402         local migrates=$(changelog_dump | grep -c "MIGRT")
15403         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15404 }
15405 run_test 160d "verify that changelog log catch the migrate event"
15406
15407 test_160e() {
15408         remote_mds_nodsh && skip "remote MDS with nodsh"
15409
15410         # Create a user
15411         changelog_register || error "changelog_register failed"
15412
15413         # Delete a future user (expect fail)
15414         local MDT0=$(facet_svc $SINGLEMDS)
15415         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15416         local rc=$?
15417
15418         if [ $rc -eq 0 ]; then
15419                 error "Deleted non-existant user cl77"
15420         elif [ $rc -ne 2 ]; then
15421                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15422         fi
15423
15424         # Clear to a bad index (1 billion should be safe)
15425         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15426         rc=$?
15427
15428         if [ $rc -eq 0 ]; then
15429                 error "Successfully cleared to invalid CL index"
15430         elif [ $rc -ne 22 ]; then
15431                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15432         fi
15433 }
15434 run_test 160e "changelog negative testing (should return errors)"
15435
15436 test_160f() {
15437         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15438         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15439                 skip "Need MDS version at least 2.10.56"
15440
15441         local mdts=$(comma_list $(mdts_nodes))
15442
15443         # Create a user
15444         changelog_register || error "first changelog_register failed"
15445         changelog_register || error "second changelog_register failed"
15446         local cl_users
15447         declare -A cl_user1
15448         declare -A cl_user2
15449         local user_rec1
15450         local user_rec2
15451         local i
15452
15453         # generate some changelog records to accumulate on each MDT
15454         # use all_char because created files should be evenly distributed
15455         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15456                 error "test_mkdir $tdir failed"
15457         log "$(date +%s): creating first files"
15458         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15459                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15460                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15461         done
15462
15463         # check changelogs have been generated
15464         local start=$SECONDS
15465         local idle_time=$((MDSCOUNT * 5 + 5))
15466         local nbcl=$(changelog_dump | wc -l)
15467         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15468
15469         for param in "changelog_max_idle_time=$idle_time" \
15470                      "changelog_gc=1" \
15471                      "changelog_min_gc_interval=2" \
15472                      "changelog_min_free_cat_entries=3"; do
15473                 local MDT0=$(facet_svc $SINGLEMDS)
15474                 local var="${param%=*}"
15475                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15476
15477                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15478                 do_nodes $mdts $LCTL set_param mdd.*.$param
15479         done
15480
15481         # force cl_user2 to be idle (1st part), but also cancel the
15482         # cl_user1 records so that it is not evicted later in the test.
15483         local sleep1=$((idle_time / 2))
15484         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15485         sleep $sleep1
15486
15487         # simulate changelog catalog almost full
15488         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15489         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15490
15491         for i in $(seq $MDSCOUNT); do
15492                 cl_users=(${CL_USERS[mds$i]})
15493                 cl_user1[mds$i]="${cl_users[0]}"
15494                 cl_user2[mds$i]="${cl_users[1]}"
15495
15496                 [ -n "${cl_user1[mds$i]}" ] ||
15497                         error "mds$i: no user registered"
15498                 [ -n "${cl_user2[mds$i]}" ] ||
15499                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15500
15501                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15502                 [ -n "$user_rec1" ] ||
15503                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15504                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15505                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15506                 [ -n "$user_rec2" ] ||
15507                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15508                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15509                      "$user_rec1 + 2 == $user_rec2"
15510                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15511                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15512                               "$user_rec1 + 2, but is $user_rec2"
15513                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15514                 [ -n "$user_rec2" ] ||
15515                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15516                 [ $user_rec1 == $user_rec2 ] ||
15517                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15518                               "$user_rec1, but is $user_rec2"
15519         done
15520
15521         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15522         local sleep2=$((idle_time - (SECONDS - start) + 1))
15523         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15524         sleep $sleep2
15525
15526         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15527         # cl_user1 should be OK because it recently processed records.
15528         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15529         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15530                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15531                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15532         done
15533
15534         # ensure gc thread is done
15535         for i in $(mdts_nodes); do
15536                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15537                         error "$i: GC-thread not done"
15538         done
15539
15540         local first_rec
15541         for (( i = 1; i <= MDSCOUNT; i++ )); do
15542                 # check cl_user1 still registered
15543                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15544                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15545                 # check cl_user2 unregistered
15546                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15547                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15548
15549                 # check changelogs are present and starting at $user_rec1 + 1
15550                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15551                 [ -n "$user_rec1" ] ||
15552                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15553                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15554                             awk '{ print $1; exit; }')
15555
15556                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15557                 [ $((user_rec1 + 1)) == $first_rec ] ||
15558                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15559         done
15560 }
15561 run_test 160f "changelog garbage collect (timestamped users)"
15562
15563 test_160g() {
15564         remote_mds_nodsh && skip "remote MDS with nodsh"
15565         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15566                 skip "Need MDS version at least 2.10.56"
15567
15568         local mdts=$(comma_list $(mdts_nodes))
15569
15570         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15571         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15572
15573         # Create a user
15574         changelog_register || error "first changelog_register failed"
15575         changelog_register || error "second changelog_register failed"
15576         local cl_users
15577         declare -A cl_user1
15578         declare -A cl_user2
15579         local user_rec1
15580         local user_rec2
15581         local i
15582
15583         # generate some changelog records to accumulate on each MDT
15584         # use all_char because created files should be evenly distributed
15585         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15586                 error "test_mkdir $tdir failed"
15587         for ((i = 0; i < MDSCOUNT; i++)); do
15588                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15589                         error "create $DIR/$tdir/d$i.1 failed"
15590         done
15591
15592         # check changelogs have been generated
15593         local nbcl=$(changelog_dump | wc -l)
15594         (( $nbcl > 0 )) || error "no changelogs found"
15595
15596         # reduce the max_idle_indexes value to make sure we exceed it
15597         for param in "changelog_max_idle_indexes=1" \
15598                      "changelog_gc=1" \
15599                      "changelog_min_gc_interval=2" \
15600                      "changelog_min_free_cat_entries=3"; do
15601                 local MDT0=$(facet_svc $SINGLEMDS)
15602                 local var="${param%=*}"
15603                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15604
15605                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15606                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15607                         error "unable to set mdd.*.$param"
15608         done
15609
15610         # simulate changelog catalog almost full
15611         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15612         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15613
15614         local start=$SECONDS
15615         for i in $(seq $MDSCOUNT); do
15616                 cl_users=(${CL_USERS[mds$i]})
15617                 cl_user1[mds$i]="${cl_users[0]}"
15618                 cl_user2[mds$i]="${cl_users[1]}"
15619
15620                 [ -n "${cl_user1[mds$i]}" ] ||
15621                         error "mds$i: no user registered"
15622                 [ -n "${cl_user2[mds$i]}" ] ||
15623                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15624
15625                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15626                 [ -n "$user_rec1" ] ||
15627                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15628                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15629                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15630                 [ -n "$user_rec2" ] ||
15631                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15632                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15633                      "$user_rec1 + 2 == $user_rec2"
15634                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15635                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15636                               "$user_rec1 + 2, but is $user_rec2"
15637                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15638                 [ -n "$user_rec2" ] ||
15639                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15640                 [ $user_rec1 == $user_rec2 ] ||
15641                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15642                               "$user_rec1, but is $user_rec2"
15643         done
15644
15645         # ensure we are past the previous changelog_min_gc_interval set above
15646         local sleep2=$((start + 2 - SECONDS))
15647         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15648
15649         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15650         # cl_user1 should be OK because it recently processed records.
15651         for ((i = 0; i < MDSCOUNT; i++)); do
15652                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15653                         error "create $DIR/$tdir/d$i.3 failed"
15654         done
15655
15656         # ensure gc thread is done
15657         for i in $(mdts_nodes); do
15658                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15659                         error "$i: GC-thread not done"
15660         done
15661
15662         local first_rec
15663         for (( i = 1; i <= MDSCOUNT; i++ )); do
15664                 # check cl_user1 still registered
15665                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15666                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15667                 # check cl_user2 unregistered
15668                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15669                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15670
15671                 # check changelogs are present and starting at $user_rec1 + 1
15672                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15673                 [ -n "$user_rec1" ] ||
15674                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15675                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15676                             awk '{ print $1; exit; }')
15677
15678                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15679                 [ $((user_rec1 + 1)) == $first_rec ] ||
15680                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15681         done
15682 }
15683 run_test 160g "changelog garbage collect (old users)"
15684
15685 test_160h() {
15686         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15687         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15688                 skip "Need MDS version at least 2.10.56"
15689
15690         local mdts=$(comma_list $(mdts_nodes))
15691
15692         # Create a user
15693         changelog_register || error "first changelog_register failed"
15694         changelog_register || error "second changelog_register failed"
15695         local cl_users
15696         declare -A cl_user1
15697         declare -A cl_user2
15698         local user_rec1
15699         local user_rec2
15700         local i
15701
15702         # generate some changelog records to accumulate on each MDT
15703         # use all_char because created files should be evenly distributed
15704         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15705                 error "test_mkdir $tdir failed"
15706         for ((i = 0; i < MDSCOUNT; i++)); do
15707                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15708                         error "create $DIR/$tdir/d$i.1 failed"
15709         done
15710
15711         # check changelogs have been generated
15712         local nbcl=$(changelog_dump | wc -l)
15713         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15714
15715         for param in "changelog_max_idle_time=10" \
15716                      "changelog_gc=1" \
15717                      "changelog_min_gc_interval=2"; do
15718                 local MDT0=$(facet_svc $SINGLEMDS)
15719                 local var="${param%=*}"
15720                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15721
15722                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15723                 do_nodes $mdts $LCTL set_param mdd.*.$param
15724         done
15725
15726         # force cl_user2 to be idle (1st part)
15727         sleep 9
15728
15729         for i in $(seq $MDSCOUNT); do
15730                 cl_users=(${CL_USERS[mds$i]})
15731                 cl_user1[mds$i]="${cl_users[0]}"
15732                 cl_user2[mds$i]="${cl_users[1]}"
15733
15734                 [ -n "${cl_user1[mds$i]}" ] ||
15735                         error "mds$i: no user registered"
15736                 [ -n "${cl_user2[mds$i]}" ] ||
15737                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15738
15739                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15740                 [ -n "$user_rec1" ] ||
15741                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15742                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15743                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15744                 [ -n "$user_rec2" ] ||
15745                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15746                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15747                      "$user_rec1 + 2 == $user_rec2"
15748                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15749                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15750                               "$user_rec1 + 2, but is $user_rec2"
15751                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15752                 [ -n "$user_rec2" ] ||
15753                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15754                 [ $user_rec1 == $user_rec2 ] ||
15755                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15756                               "$user_rec1, but is $user_rec2"
15757         done
15758
15759         # force cl_user2 to be idle (2nd part) and to reach
15760         # changelog_max_idle_time
15761         sleep 2
15762
15763         # force each GC-thread start and block then
15764         # one per MDT/MDD, set fail_val accordingly
15765         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15766         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15767
15768         # generate more changelogs to trigger fail_loc
15769         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15770                 error "create $DIR/$tdir/${tfile}bis failed"
15771
15772         # stop MDT to stop GC-thread, should be done in back-ground as it will
15773         # block waiting for the thread to be released and exit
15774         declare -A stop_pids
15775         for i in $(seq $MDSCOUNT); do
15776                 stop mds$i &
15777                 stop_pids[mds$i]=$!
15778         done
15779
15780         for i in $(mdts_nodes); do
15781                 local facet
15782                 local nb=0
15783                 local facets=$(facets_up_on_host $i)
15784
15785                 for facet in ${facets//,/ }; do
15786                         if [[ $facet == mds* ]]; then
15787                                 nb=$((nb + 1))
15788                         fi
15789                 done
15790                 # ensure each MDS's gc threads are still present and all in "R"
15791                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15792                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15793                         error "$i: expected $nb GC-thread"
15794                 wait_update $i \
15795                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15796                         "R" 20 ||
15797                         error "$i: GC-thread not found in R-state"
15798                 # check umounts of each MDT on MDS have reached kthread_stop()
15799                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15800                         error "$i: expected $nb umount"
15801                 wait_update $i \
15802                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15803                         error "$i: umount not found in D-state"
15804         done
15805
15806         # release all GC-threads
15807         do_nodes $mdts $LCTL set_param fail_loc=0
15808
15809         # wait for MDT stop to complete
15810         for i in $(seq $MDSCOUNT); do
15811                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15812         done
15813
15814         # XXX
15815         # may try to check if any orphan changelog records are present
15816         # via ldiskfs/zfs and llog_reader...
15817
15818         # re-start/mount MDTs
15819         for i in $(seq $MDSCOUNT); do
15820                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15821                         error "Fail to start mds$i"
15822         done
15823
15824         local first_rec
15825         for i in $(seq $MDSCOUNT); do
15826                 # check cl_user1 still registered
15827                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15829                 # check cl_user2 unregistered
15830                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15831                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15832
15833                 # check changelogs are present and starting at $user_rec1 + 1
15834                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15835                 [ -n "$user_rec1" ] ||
15836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15837                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15838                             awk '{ print $1; exit; }')
15839
15840                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15841                 [ $((user_rec1 + 1)) == $first_rec ] ||
15842                         error "mds$i: first index should be $user_rec1 + 1, " \
15843                               "but is $first_rec"
15844         done
15845 }
15846 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15847               "during mount"
15848
15849 test_160i() {
15850
15851         local mdts=$(comma_list $(mdts_nodes))
15852
15853         changelog_register || error "first changelog_register failed"
15854
15855         # generate some changelog records to accumulate on each MDT
15856         # use all_char because created files should be evenly distributed
15857         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15858                 error "test_mkdir $tdir failed"
15859         for ((i = 0; i < MDSCOUNT; i++)); do
15860                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15861                         error "create $DIR/$tdir/d$i.1 failed"
15862         done
15863
15864         # check changelogs have been generated
15865         local nbcl=$(changelog_dump | wc -l)
15866         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15867
15868         # simulate race between register and unregister
15869         # XXX as fail_loc is set per-MDS, with DNE configs the race
15870         # simulation will only occur for one MDT per MDS and for the
15871         # others the normal race scenario will take place
15872         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15873         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15874         do_nodes $mdts $LCTL set_param fail_val=1
15875
15876         # unregister 1st user
15877         changelog_deregister &
15878         local pid1=$!
15879         # wait some time for deregister work to reach race rdv
15880         sleep 2
15881         # register 2nd user
15882         changelog_register || error "2nd user register failed"
15883
15884         wait $pid1 || error "1st user deregister failed"
15885
15886         local i
15887         local last_rec
15888         declare -A LAST_REC
15889         for i in $(seq $MDSCOUNT); do
15890                 if changelog_users mds$i | grep "^cl"; then
15891                         # make sure new records are added with one user present
15892                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15893                                           awk '/^current.index:/ { print $NF }')
15894                 else
15895                         error "mds$i has no user registered"
15896                 fi
15897         done
15898
15899         # generate more changelog records to accumulate on each MDT
15900         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15901                 error "create $DIR/$tdir/${tfile}bis failed"
15902
15903         for i in $(seq $MDSCOUNT); do
15904                 last_rec=$(changelog_users $SINGLEMDS |
15905                            awk '/^current.index:/ { print $NF }')
15906                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15907                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15908                         error "changelogs are off on mds$i"
15909         done
15910 }
15911 run_test 160i "changelog user register/unregister race"
15912
15913 test_160j() {
15914         remote_mds_nodsh && skip "remote MDS with nodsh"
15915         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15916                 skip "Need MDS version at least 2.12.56"
15917
15918         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15919         stack_trap "umount $MOUNT2" EXIT
15920
15921         changelog_register || error "first changelog_register failed"
15922         stack_trap "changelog_deregister" EXIT
15923
15924         # generate some changelog
15925         # use all_char because created files should be evenly distributed
15926         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15927                 error "mkdir $tdir failed"
15928         for ((i = 0; i < MDSCOUNT; i++)); do
15929                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15930                         error "create $DIR/$tdir/d$i.1 failed"
15931         done
15932
15933         # open the changelog device
15934         exec 3>/dev/changelog-$FSNAME-MDT0000
15935         stack_trap "exec 3>&-" EXIT
15936         exec 4</dev/changelog-$FSNAME-MDT0000
15937         stack_trap "exec 4<&-" EXIT
15938
15939         # umount the first lustre mount
15940         umount $MOUNT
15941         stack_trap "mount_client $MOUNT" EXIT
15942
15943         # read changelog, which may or may not fail, but should not crash
15944         cat <&4 >/dev/null
15945
15946         # clear changelog
15947         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15948         changelog_users $SINGLEMDS | grep -q $cl_user ||
15949                 error "User $cl_user not found in changelog_users"
15950
15951         printf 'clear:'$cl_user':0' >&3
15952 }
15953 run_test 160j "client can be umounted while its chanangelog is being used"
15954
15955 test_160k() {
15956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15957         remote_mds_nodsh && skip "remote MDS with nodsh"
15958
15959         mkdir -p $DIR/$tdir/1/1
15960
15961         changelog_register || error "changelog_register failed"
15962         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15963
15964         changelog_users $SINGLEMDS | grep -q $cl_user ||
15965                 error "User '$cl_user' not found in changelog_users"
15966 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15967         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15968         rmdir $DIR/$tdir/1/1 & sleep 1
15969         mkdir $DIR/$tdir/2
15970         touch $DIR/$tdir/2/2
15971         rm -rf $DIR/$tdir/2
15972
15973         wait
15974         sleep 4
15975
15976         changelog_dump | grep rmdir || error "rmdir not recorded"
15977 }
15978 run_test 160k "Verify that changelog records are not lost"
15979
15980 # Verifies that a file passed as a parameter has recently had an operation
15981 # performed on it that has generated an MTIME changelog which contains the
15982 # correct parent FID. As files might reside on a different MDT from the
15983 # parent directory in DNE configurations, the FIDs are translated to paths
15984 # before being compared, which should be identical
15985 compare_mtime_changelog() {
15986         local file="${1}"
15987         local mdtidx
15988         local mtime
15989         local cl_fid
15990         local pdir
15991         local dir
15992
15993         mdtidx=$($LFS getstripe --mdt-index $file)
15994         mdtidx=$(printf "%04x" $mdtidx)
15995
15996         # Obtain the parent FID from the MTIME changelog
15997         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15998         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15999
16000         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16001         [ -z "$cl_fid" ] && error "parent FID not present"
16002
16003         # Verify that the path for the parent FID is the same as the path for
16004         # the test directory
16005         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16006
16007         dir=$(dirname $1)
16008
16009         [[ "${pdir%/}" == "$dir" ]] ||
16010                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16011 }
16012
16013 test_160l() {
16014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16015
16016         remote_mds_nodsh && skip "remote MDS with nodsh"
16017         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16018                 skip "Need MDS version at least 2.13.55"
16019
16020         local cl_user
16021
16022         changelog_register || error "changelog_register failed"
16023         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16024
16025         changelog_users $SINGLEMDS | grep -q $cl_user ||
16026                 error "User '$cl_user' not found in changelog_users"
16027
16028         # Clear some types so that MTIME changelogs are generated
16029         changelog_chmask "-CREAT"
16030         changelog_chmask "-CLOSE"
16031
16032         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16033
16034         # Test CL_MTIME during setattr
16035         touch $DIR/$tdir/$tfile
16036         compare_mtime_changelog $DIR/$tdir/$tfile
16037
16038         # Test CL_MTIME during close
16039         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16040         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16041 }
16042 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16043
16044 test_160m() {
16045         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16046         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16047                 skip "Need MDS version at least 2.14.51"
16048         local cl_users
16049         local cl_user1
16050         local cl_user2
16051         local pid1
16052
16053         # Create a user
16054         changelog_register || error "first changelog_register failed"
16055         changelog_register || error "second changelog_register failed"
16056
16057         cl_users=(${CL_USERS[mds1]})
16058         cl_user1="${cl_users[0]}"
16059         cl_user2="${cl_users[1]}"
16060         # generate some changelog records to accumulate on MDT0
16061         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16062         createmany -m $DIR/$tdir/$tfile 50 ||
16063                 error "create $DIR/$tdir/$tfile failed"
16064         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16065         rm -f $DIR/$tdir
16066
16067         # check changelogs have been generated
16068         local nbcl=$(changelog_dump | wc -l)
16069         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16070
16071 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16072         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16073
16074         __changelog_clear mds1 $cl_user1 +10
16075         __changelog_clear mds1 $cl_user2 0 &
16076         pid1=$!
16077         sleep 2
16078         __changelog_clear mds1 $cl_user1 0 ||
16079                 error "fail to cancel record for $cl_user1"
16080         wait $pid1
16081         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16082 }
16083 run_test 160m "Changelog clear race"
16084
16085
16086 test_161a() {
16087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16088
16089         test_mkdir -c1 $DIR/$tdir
16090         cp /etc/hosts $DIR/$tdir/$tfile
16091         test_mkdir -c1 $DIR/$tdir/foo1
16092         test_mkdir -c1 $DIR/$tdir/foo2
16093         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16094         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16096         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16097         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16098         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16099                 $LFS fid2path $DIR $FID
16100                 error "bad link ea"
16101         fi
16102         # middle
16103         rm $DIR/$tdir/foo2/zachary
16104         # last
16105         rm $DIR/$tdir/foo2/thor
16106         # first
16107         rm $DIR/$tdir/$tfile
16108         # rename
16109         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16110         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16111                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16112         rm $DIR/$tdir/foo2/maggie
16113
16114         # overflow the EA
16115         local longname=$tfile.avg_len_is_thirty_two_
16116         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16117                 error_noexit 'failed to unlink many hardlinks'" EXIT
16118         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16119                 error "failed to hardlink many files"
16120         links=$($LFS fid2path $DIR $FID | wc -l)
16121         echo -n "${links}/1000 links in link EA"
16122         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16123 }
16124 run_test 161a "link ea sanity"
16125
16126 test_161b() {
16127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16128         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16129
16130         local MDTIDX=1
16131         local remote_dir=$DIR/$tdir/remote_dir
16132
16133         mkdir -p $DIR/$tdir
16134         $LFS mkdir -i $MDTIDX $remote_dir ||
16135                 error "create remote directory failed"
16136
16137         cp /etc/hosts $remote_dir/$tfile
16138         mkdir -p $remote_dir/foo1
16139         mkdir -p $remote_dir/foo2
16140         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16141         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16142         ln $remote_dir/$tfile $remote_dir/foo1/luna
16143         ln $remote_dir/$tfile $remote_dir/foo2/thor
16144
16145         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16146                      tr -d ']')
16147         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16148                 $LFS fid2path $DIR $FID
16149                 error "bad link ea"
16150         fi
16151         # middle
16152         rm $remote_dir/foo2/zachary
16153         # last
16154         rm $remote_dir/foo2/thor
16155         # first
16156         rm $remote_dir/$tfile
16157         # rename
16158         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16159         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16160         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16161                 $LFS fid2path $DIR $FID
16162                 error "bad link rename"
16163         fi
16164         rm $remote_dir/foo2/maggie
16165
16166         # overflow the EA
16167         local longname=filename_avg_len_is_thirty_two_
16168         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16169                 error "failed to hardlink many files"
16170         links=$($LFS fid2path $DIR $FID | wc -l)
16171         echo -n "${links}/1000 links in link EA"
16172         [[ ${links} -gt 60 ]] ||
16173                 error "expected at least 60 links in link EA"
16174         unlinkmany $remote_dir/foo2/$longname 1000 ||
16175         error "failed to unlink many hardlinks"
16176 }
16177 run_test 161b "link ea sanity under remote directory"
16178
16179 test_161c() {
16180         remote_mds_nodsh && skip "remote MDS with nodsh"
16181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16182         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16183                 skip "Need MDS version at least 2.1.5"
16184
16185         # define CLF_RENAME_LAST 0x0001
16186         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16187         changelog_register || error "changelog_register failed"
16188
16189         rm -rf $DIR/$tdir
16190         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16191         touch $DIR/$tdir/foo_161c
16192         touch $DIR/$tdir/bar_161c
16193         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16194         changelog_dump | grep RENME | tail -n 5
16195         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16196         changelog_clear 0 || error "changelog_clear failed"
16197         if [ x$flags != "x0x1" ]; then
16198                 error "flag $flags is not 0x1"
16199         fi
16200
16201         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16202         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16203         touch $DIR/$tdir/foo_161c
16204         touch $DIR/$tdir/bar_161c
16205         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16206         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16207         changelog_dump | grep RENME | tail -n 5
16208         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16209         changelog_clear 0 || error "changelog_clear failed"
16210         if [ x$flags != "x0x0" ]; then
16211                 error "flag $flags is not 0x0"
16212         fi
16213         echo "rename overwrite a target having nlink > 1," \
16214                 "changelog record has flags of $flags"
16215
16216         # rename doesn't overwrite a target (changelog flag 0x0)
16217         touch $DIR/$tdir/foo_161c
16218         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16219         changelog_dump | grep RENME | tail -n 5
16220         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16221         changelog_clear 0 || error "changelog_clear failed"
16222         if [ x$flags != "x0x0" ]; then
16223                 error "flag $flags is not 0x0"
16224         fi
16225         echo "rename doesn't overwrite a target," \
16226                 "changelog record has flags of $flags"
16227
16228         # define CLF_UNLINK_LAST 0x0001
16229         # unlink a file having nlink = 1 (changelog flag 0x1)
16230         rm -f $DIR/$tdir/foo2_161c
16231         changelog_dump | grep UNLNK | tail -n 5
16232         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16233         changelog_clear 0 || error "changelog_clear failed"
16234         if [ x$flags != "x0x1" ]; then
16235                 error "flag $flags is not 0x1"
16236         fi
16237         echo "unlink a file having nlink = 1," \
16238                 "changelog record has flags of $flags"
16239
16240         # unlink a file having nlink > 1 (changelog flag 0x0)
16241         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16242         rm -f $DIR/$tdir/foobar_161c
16243         changelog_dump | grep UNLNK | tail -n 5
16244         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16245         changelog_clear 0 || error "changelog_clear failed"
16246         if [ x$flags != "x0x0" ]; then
16247                 error "flag $flags is not 0x0"
16248         fi
16249         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16250 }
16251 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16252
16253 test_161d() {
16254         remote_mds_nodsh && skip "remote MDS with nodsh"
16255         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16256
16257         local pid
16258         local fid
16259
16260         changelog_register || error "changelog_register failed"
16261
16262         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16263         # interfer with $MOUNT/.lustre/fid/ access
16264         mkdir $DIR/$tdir
16265         [[ $? -eq 0 ]] || error "mkdir failed"
16266
16267         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16268         $LCTL set_param fail_loc=0x8000140c
16269         # 5s pause
16270         $LCTL set_param fail_val=5
16271
16272         # create file
16273         echo foofoo > $DIR/$tdir/$tfile &
16274         pid=$!
16275
16276         # wait for create to be delayed
16277         sleep 2
16278
16279         ps -p $pid
16280         [[ $? -eq 0 ]] || error "create should be blocked"
16281
16282         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16283         stack_trap "rm -f $tempfile"
16284         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16285         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16286         # some delay may occur during ChangeLog publishing and file read just
16287         # above, that could allow file write to happen finally
16288         [[ -s $tempfile ]] && echo "file should be empty"
16289
16290         $LCTL set_param fail_loc=0
16291
16292         wait $pid
16293         [[ $? -eq 0 ]] || error "create failed"
16294 }
16295 run_test 161d "create with concurrent .lustre/fid access"
16296
16297 check_path() {
16298         local expected="$1"
16299         shift
16300         local fid="$2"
16301
16302         local path
16303         path=$($LFS fid2path "$@")
16304         local rc=$?
16305
16306         if [ $rc -ne 0 ]; then
16307                 error "path looked up of '$expected' failed: rc=$rc"
16308         elif [ "$path" != "$expected" ]; then
16309                 error "path looked up '$path' instead of '$expected'"
16310         else
16311                 echo "FID '$fid' resolves to path '$path' as expected"
16312         fi
16313 }
16314
16315 test_162a() { # was test_162
16316         test_mkdir -p -c1 $DIR/$tdir/d2
16317         touch $DIR/$tdir/d2/$tfile
16318         touch $DIR/$tdir/d2/x1
16319         touch $DIR/$tdir/d2/x2
16320         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16321         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16322         # regular file
16323         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16324         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16325
16326         # softlink
16327         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16328         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16329         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16330
16331         # softlink to wrong file
16332         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16333         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16334         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16335
16336         # hardlink
16337         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16338         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16339         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16340         # fid2path dir/fsname should both work
16341         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16342         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16343
16344         # hardlink count: check that there are 2 links
16345         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16346         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16347
16348         # hardlink indexing: remove the first link
16349         rm $DIR/$tdir/d2/p/q/r/hlink
16350         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16351 }
16352 run_test 162a "path lookup sanity"
16353
16354 test_162b() {
16355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16357
16358         mkdir $DIR/$tdir
16359         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16360                                 error "create striped dir failed"
16361
16362         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16363                                         tail -n 1 | awk '{print $2}')
16364         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16365
16366         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16367         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16368
16369         # regular file
16370         for ((i=0;i<5;i++)); do
16371                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16372                         error "get fid for f$i failed"
16373                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16374
16375                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16376                         error "get fid for d$i failed"
16377                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16378         done
16379
16380         return 0
16381 }
16382 run_test 162b "striped directory path lookup sanity"
16383
16384 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16385 test_162c() {
16386         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16387                 skip "Need MDS version at least 2.7.51"
16388
16389         local lpath=$tdir.local
16390         local rpath=$tdir.remote
16391
16392         test_mkdir $DIR/$lpath
16393         test_mkdir $DIR/$rpath
16394
16395         for ((i = 0; i <= 101; i++)); do
16396                 lpath="$lpath/$i"
16397                 mkdir $DIR/$lpath
16398                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16399                         error "get fid for local directory $DIR/$lpath failed"
16400                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16401
16402                 rpath="$rpath/$i"
16403                 test_mkdir $DIR/$rpath
16404                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16405                         error "get fid for remote directory $DIR/$rpath failed"
16406                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16407         done
16408
16409         return 0
16410 }
16411 run_test 162c "fid2path works with paths 100 or more directories deep"
16412
16413 oalr_event_count() {
16414         local event="${1}"
16415         local trace="${2}"
16416
16417         awk -v name="${FSNAME}-OST0000" \
16418             -v event="${event}" \
16419             '$1 == "TRACE" && $2 == event && $3 == name' \
16420             "${trace}" |
16421         wc -l
16422 }
16423
16424 oalr_expect_event_count() {
16425         local event="${1}"
16426         local trace="${2}"
16427         local expect="${3}"
16428         local count
16429
16430         count=$(oalr_event_count "${event}" "${trace}")
16431         if ((count == expect)); then
16432                 return 0
16433         fi
16434
16435         error_noexit "${event} event count was '${count}', expected ${expect}"
16436         cat "${trace}" >&2
16437         exit 1
16438 }
16439
16440 cleanup_165() {
16441         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16442         stop ost1
16443         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16444 }
16445
16446 setup_165() {
16447         sync # Flush previous IOs so we can count log entries.
16448         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16449         stack_trap cleanup_165 EXIT
16450 }
16451
16452 test_165a() {
16453         local trace="/tmp/${tfile}.trace"
16454         local rc
16455         local count
16456
16457         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16458                 skip "OFD access log unsupported"
16459
16460         setup_165
16461         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16462         sleep 5
16463
16464         do_facet ost1 ofd_access_log_reader --list
16465         stop ost1
16466
16467         do_facet ost1 killall -TERM ofd_access_log_reader
16468         wait
16469         rc=$?
16470
16471         if ((rc != 0)); then
16472                 error "ofd_access_log_reader exited with rc = '${rc}'"
16473         fi
16474
16475         # Parse trace file for discovery events:
16476         oalr_expect_event_count alr_log_add "${trace}" 1
16477         oalr_expect_event_count alr_log_eof "${trace}" 1
16478         oalr_expect_event_count alr_log_free "${trace}" 1
16479 }
16480 run_test 165a "ofd access log discovery"
16481
16482 test_165b() {
16483         local trace="/tmp/${tfile}.trace"
16484         local file="${DIR}/${tfile}"
16485         local pfid1
16486         local pfid2
16487         local -a entry
16488         local rc
16489         local count
16490         local size
16491         local flags
16492
16493         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16494                 skip "OFD access log unsupported"
16495
16496         setup_165
16497         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16498         sleep 5
16499
16500         do_facet ost1 ofd_access_log_reader --list
16501
16502         lfs setstripe -c 1 -i 0 "${file}"
16503         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16504                 error "cannot create '${file}'"
16505
16506         sleep 5
16507         do_facet ost1 killall -TERM ofd_access_log_reader
16508         wait
16509         rc=$?
16510
16511         if ((rc != 0)); then
16512                 error "ofd_access_log_reader exited with rc = '${rc}'"
16513         fi
16514
16515         oalr_expect_event_count alr_log_entry "${trace}" 1
16516
16517         pfid1=$($LFS path2fid "${file}")
16518
16519         # 1     2             3   4    5     6   7    8    9     10
16520         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16521         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16522
16523         echo "entry = '${entry[*]}'" >&2
16524
16525         pfid2=${entry[4]}
16526         if [[ "${pfid1}" != "${pfid2}" ]]; then
16527                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16528         fi
16529
16530         size=${entry[8]}
16531         if ((size != 1048576)); then
16532                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16533         fi
16534
16535         flags=${entry[10]}
16536         if [[ "${flags}" != "w" ]]; then
16537                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16538         fi
16539
16540         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16541         sleep 5
16542
16543         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16544                 error "cannot read '${file}'"
16545         sleep 5
16546
16547         do_facet ost1 killall -TERM ofd_access_log_reader
16548         wait
16549         rc=$?
16550
16551         if ((rc != 0)); then
16552                 error "ofd_access_log_reader exited with rc = '${rc}'"
16553         fi
16554
16555         oalr_expect_event_count alr_log_entry "${trace}" 1
16556
16557         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16558         echo "entry = '${entry[*]}'" >&2
16559
16560         pfid2=${entry[4]}
16561         if [[ "${pfid1}" != "${pfid2}" ]]; then
16562                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16563         fi
16564
16565         size=${entry[8]}
16566         if ((size != 524288)); then
16567                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16568         fi
16569
16570         flags=${entry[10]}
16571         if [[ "${flags}" != "r" ]]; then
16572                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16573         fi
16574 }
16575 run_test 165b "ofd access log entries are produced and consumed"
16576
16577 test_165c() {
16578         local trace="/tmp/${tfile}.trace"
16579         local file="${DIR}/${tdir}/${tfile}"
16580
16581         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16582                 skip "OFD access log unsupported"
16583
16584         test_mkdir "${DIR}/${tdir}"
16585
16586         setup_165
16587         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16588         sleep 5
16589
16590         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16591
16592         # 4096 / 64 = 64. Create twice as many entries.
16593         for ((i = 0; i < 128; i++)); do
16594                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16595                         error "cannot create file"
16596         done
16597
16598         sync
16599
16600         do_facet ost1 killall -TERM ofd_access_log_reader
16601         wait
16602         rc=$?
16603         if ((rc != 0)); then
16604                 error "ofd_access_log_reader exited with rc = '${rc}'"
16605         fi
16606
16607         unlinkmany  "${file}-%d" 128
16608 }
16609 run_test 165c "full ofd access logs do not block IOs"
16610
16611 oal_get_read_count() {
16612         local stats="$1"
16613
16614         # STATS lustre-OST0001 alr_read_count 1
16615
16616         do_facet ost1 cat "${stats}" |
16617         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16618              END { print count; }'
16619 }
16620
16621 oal_expect_read_count() {
16622         local stats="$1"
16623         local count
16624         local expect="$2"
16625
16626         # Ask ofd_access_log_reader to write stats.
16627         do_facet ost1 killall -USR1 ofd_access_log_reader
16628
16629         # Allow some time for things to happen.
16630         sleep 1
16631
16632         count=$(oal_get_read_count "${stats}")
16633         if ((count == expect)); then
16634                 return 0
16635         fi
16636
16637         error_noexit "bad read count, got ${count}, expected ${expect}"
16638         do_facet ost1 cat "${stats}" >&2
16639         exit 1
16640 }
16641
16642 test_165d() {
16643         local stats="/tmp/${tfile}.stats"
16644         local file="${DIR}/${tdir}/${tfile}"
16645         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16646
16647         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16648                 skip "OFD access log unsupported"
16649
16650         test_mkdir "${DIR}/${tdir}"
16651
16652         setup_165
16653         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16654         sleep 5
16655
16656         lfs setstripe -c 1 -i 0 "${file}"
16657
16658         do_facet ost1 lctl set_param "${param}=rw"
16659         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16660                 error "cannot create '${file}'"
16661         oal_expect_read_count "${stats}" 1
16662
16663         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16664                 error "cannot read '${file}'"
16665         oal_expect_read_count "${stats}" 2
16666
16667         do_facet ost1 lctl set_param "${param}=r"
16668         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16669                 error "cannot create '${file}'"
16670         oal_expect_read_count "${stats}" 2
16671
16672         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16673                 error "cannot read '${file}'"
16674         oal_expect_read_count "${stats}" 3
16675
16676         do_facet ost1 lctl set_param "${param}=w"
16677         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16678                 error "cannot create '${file}'"
16679         oal_expect_read_count "${stats}" 4
16680
16681         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16682                 error "cannot read '${file}'"
16683         oal_expect_read_count "${stats}" 4
16684
16685         do_facet ost1 lctl set_param "${param}=0"
16686         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16687                 error "cannot create '${file}'"
16688         oal_expect_read_count "${stats}" 4
16689
16690         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16691                 error "cannot read '${file}'"
16692         oal_expect_read_count "${stats}" 4
16693
16694         do_facet ost1 killall -TERM ofd_access_log_reader
16695         wait
16696         rc=$?
16697         if ((rc != 0)); then
16698                 error "ofd_access_log_reader exited with rc = '${rc}'"
16699         fi
16700 }
16701 run_test 165d "ofd_access_log mask works"
16702
16703 test_165e() {
16704         local stats="/tmp/${tfile}.stats"
16705         local file0="${DIR}/${tdir}-0/${tfile}"
16706         local file1="${DIR}/${tdir}-1/${tfile}"
16707
16708         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16709                 skip "OFD access log unsupported"
16710
16711         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16712
16713         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16714         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16715
16716         lfs setstripe -c 1 -i 0 "${file0}"
16717         lfs setstripe -c 1 -i 0 "${file1}"
16718
16719         setup_165
16720         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16721         sleep 5
16722
16723         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16724                 error "cannot create '${file0}'"
16725         sync
16726         oal_expect_read_count "${stats}" 0
16727
16728         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16729                 error "cannot create '${file1}'"
16730         sync
16731         oal_expect_read_count "${stats}" 1
16732
16733         do_facet ost1 killall -TERM ofd_access_log_reader
16734         wait
16735         rc=$?
16736         if ((rc != 0)); then
16737                 error "ofd_access_log_reader exited with rc = '${rc}'"
16738         fi
16739 }
16740 run_test 165e "ofd_access_log MDT index filter works"
16741
16742 test_165f() {
16743         local trace="/tmp/${tfile}.trace"
16744         local rc
16745         local count
16746
16747         setup_165
16748         do_facet ost1 timeout 60 ofd_access_log_reader \
16749                 --exit-on-close --debug=- --trace=- > "${trace}" &
16750         sleep 5
16751         stop ost1
16752
16753         wait
16754         rc=$?
16755
16756         if ((rc != 0)); then
16757                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16758                 cat "${trace}"
16759                 exit 1
16760         fi
16761 }
16762 run_test 165f "ofd_access_log_reader --exit-on-close works"
16763
16764 test_169() {
16765         # do directio so as not to populate the page cache
16766         log "creating a 10 Mb file"
16767         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16768                 error "multiop failed while creating a file"
16769         log "starting reads"
16770         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16771         log "truncating the file"
16772         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16773                 error "multiop failed while truncating the file"
16774         log "killing dd"
16775         kill %+ || true # reads might have finished
16776         echo "wait until dd is finished"
16777         wait
16778         log "removing the temporary file"
16779         rm -rf $DIR/$tfile || error "tmp file removal failed"
16780 }
16781 run_test 169 "parallel read and truncate should not deadlock"
16782
16783 test_170() {
16784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16785
16786         $LCTL clear     # bug 18514
16787         $LCTL debug_daemon start $TMP/${tfile}_log_good
16788         touch $DIR/$tfile
16789         $LCTL debug_daemon stop
16790         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16791                 error "sed failed to read log_good"
16792
16793         $LCTL debug_daemon start $TMP/${tfile}_log_good
16794         rm -rf $DIR/$tfile
16795         $LCTL debug_daemon stop
16796
16797         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16798                error "lctl df log_bad failed"
16799
16800         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16801         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16802
16803         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16804         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16805
16806         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16807                 error "bad_line good_line1 good_line2 are empty"
16808
16809         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16810         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16811         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16812
16813         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16814         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16815         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16816
16817         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16818                 error "bad_line_new good_line_new are empty"
16819
16820         local expected_good=$((good_line1 + good_line2*2))
16821
16822         rm -f $TMP/${tfile}*
16823         # LU-231, short malformed line may not be counted into bad lines
16824         if [ $bad_line -ne $bad_line_new ] &&
16825                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16826                 error "expected $bad_line bad lines, but got $bad_line_new"
16827                 return 1
16828         fi
16829
16830         if [ $expected_good -ne $good_line_new ]; then
16831                 error "expected $expected_good good lines, but got $good_line_new"
16832                 return 2
16833         fi
16834         true
16835 }
16836 run_test 170 "test lctl df to handle corrupted log ====================="
16837
16838 test_171() { # bug20592
16839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16840
16841         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16842         $LCTL set_param fail_loc=0x50e
16843         $LCTL set_param fail_val=3000
16844         multiop_bg_pause $DIR/$tfile O_s || true
16845         local MULTIPID=$!
16846         kill -USR1 $MULTIPID
16847         # cause log dump
16848         sleep 3
16849         wait $MULTIPID
16850         if dmesg | grep "recursive fault"; then
16851                 error "caught a recursive fault"
16852         fi
16853         $LCTL set_param fail_loc=0
16854         true
16855 }
16856 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16857
16858 # it would be good to share it with obdfilter-survey/iokit-libecho code
16859 setup_obdecho_osc () {
16860         local rc=0
16861         local ost_nid=$1
16862         local obdfilter_name=$2
16863         echo "Creating new osc for $obdfilter_name on $ost_nid"
16864         # make sure we can find loopback nid
16865         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16866
16867         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16868                            ${obdfilter_name}_osc_UUID || rc=2; }
16869         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16870                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16871         return $rc
16872 }
16873
16874 cleanup_obdecho_osc () {
16875         local obdfilter_name=$1
16876         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16877         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16878         return 0
16879 }
16880
16881 obdecho_test() {
16882         local OBD=$1
16883         local node=$2
16884         local pages=${3:-64}
16885         local rc=0
16886         local id
16887
16888         local count=10
16889         local obd_size=$(get_obd_size $node $OBD)
16890         local page_size=$(get_page_size $node)
16891         if [[ -n "$obd_size" ]]; then
16892                 local new_count=$((obd_size / (pages * page_size / 1024)))
16893                 [[ $new_count -ge $count ]] || count=$new_count
16894         fi
16895
16896         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16897         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16898                            rc=2; }
16899         if [ $rc -eq 0 ]; then
16900             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16901             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16902         fi
16903         echo "New object id is $id"
16904         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16905                            rc=4; }
16906         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16907                            "test_brw $count w v $pages $id" || rc=4; }
16908         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16909                            rc=4; }
16910         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16911                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16912         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16913                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16914         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16915         return $rc
16916 }
16917
16918 test_180a() {
16919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16920
16921         if ! [ -d /sys/fs/lustre/echo_client ] &&
16922            ! module_loaded obdecho; then
16923                 load_module obdecho/obdecho &&
16924                         stack_trap "rmmod obdecho" EXIT ||
16925                         error "unable to load obdecho on client"
16926         fi
16927
16928         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16929         local host=$($LCTL get_param -n osc.$osc.import |
16930                      awk '/current_connection:/ { print $2 }' )
16931         local target=$($LCTL get_param -n osc.$osc.import |
16932                        awk '/target:/ { print $2 }' )
16933         target=${target%_UUID}
16934
16935         if [ -n "$target" ]; then
16936                 setup_obdecho_osc $host $target &&
16937                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16938                         { error "obdecho setup failed with $?"; return; }
16939
16940                 obdecho_test ${target}_osc client ||
16941                         error "obdecho_test failed on ${target}_osc"
16942         else
16943                 $LCTL get_param osc.$osc.import
16944                 error "there is no osc.$osc.import target"
16945         fi
16946 }
16947 run_test 180a "test obdecho on osc"
16948
16949 test_180b() {
16950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16951         remote_ost_nodsh && skip "remote OST with nodsh"
16952
16953         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16954                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16955                 error "failed to load module obdecho"
16956
16957         local target=$(do_facet ost1 $LCTL dl |
16958                        awk '/obdfilter/ { print $4; exit; }')
16959
16960         if [ -n "$target" ]; then
16961                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16962         else
16963                 do_facet ost1 $LCTL dl
16964                 error "there is no obdfilter target on ost1"
16965         fi
16966 }
16967 run_test 180b "test obdecho directly on obdfilter"
16968
16969 test_180c() { # LU-2598
16970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16971         remote_ost_nodsh && skip "remote OST with nodsh"
16972         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16973                 skip "Need MDS version at least 2.4.0"
16974
16975         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16976                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16977                 error "failed to load module obdecho"
16978
16979         local target=$(do_facet ost1 $LCTL dl |
16980                        awk '/obdfilter/ { print $4; exit; }')
16981
16982         if [ -n "$target" ]; then
16983                 local pages=16384 # 64MB bulk I/O RPC size
16984
16985                 obdecho_test "$target" ost1 "$pages" ||
16986                         error "obdecho_test with pages=$pages failed with $?"
16987         else
16988                 do_facet ost1 $LCTL dl
16989                 error "there is no obdfilter target on ost1"
16990         fi
16991 }
16992 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16993
16994 test_181() { # bug 22177
16995         test_mkdir $DIR/$tdir
16996         # create enough files to index the directory
16997         createmany -o $DIR/$tdir/foobar 4000
16998         # print attributes for debug purpose
16999         lsattr -d .
17000         # open dir
17001         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17002         MULTIPID=$!
17003         # remove the files & current working dir
17004         unlinkmany $DIR/$tdir/foobar 4000
17005         rmdir $DIR/$tdir
17006         kill -USR1 $MULTIPID
17007         wait $MULTIPID
17008         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17009         return 0
17010 }
17011 run_test 181 "Test open-unlinked dir ========================"
17012
17013 test_182() {
17014         local fcount=1000
17015         local tcount=10
17016
17017         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17018
17019         $LCTL set_param mdc.*.rpc_stats=clear
17020
17021         for (( i = 0; i < $tcount; i++ )) ; do
17022                 mkdir $DIR/$tdir/$i
17023         done
17024
17025         for (( i = 0; i < $tcount; i++ )) ; do
17026                 createmany -o $DIR/$tdir/$i/f- $fcount &
17027         done
17028         wait
17029
17030         for (( i = 0; i < $tcount; i++ )) ; do
17031                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17032         done
17033         wait
17034
17035         $LCTL get_param mdc.*.rpc_stats
17036
17037         rm -rf $DIR/$tdir
17038 }
17039 run_test 182 "Test parallel modify metadata operations ================"
17040
17041 test_183() { # LU-2275
17042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17043         remote_mds_nodsh && skip "remote MDS with nodsh"
17044         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17045                 skip "Need MDS version at least 2.3.56"
17046
17047         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17048         echo aaa > $DIR/$tdir/$tfile
17049
17050 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17051         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17052
17053         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17054         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17055
17056         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17057
17058         # Flush negative dentry cache
17059         touch $DIR/$tdir/$tfile
17060
17061         # We are not checking for any leaked references here, they'll
17062         # become evident next time we do cleanup with module unload.
17063         rm -rf $DIR/$tdir
17064 }
17065 run_test 183 "No crash or request leak in case of strange dispositions ========"
17066
17067 # test suite 184 is for LU-2016, LU-2017
17068 test_184a() {
17069         check_swap_layouts_support
17070
17071         dir0=$DIR/$tdir/$testnum
17072         test_mkdir -p -c1 $dir0
17073         ref1=/etc/passwd
17074         ref2=/etc/group
17075         file1=$dir0/f1
17076         file2=$dir0/f2
17077         $LFS setstripe -c1 $file1
17078         cp $ref1 $file1
17079         $LFS setstripe -c2 $file2
17080         cp $ref2 $file2
17081         gen1=$($LFS getstripe -g $file1)
17082         gen2=$($LFS getstripe -g $file2)
17083
17084         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17085         gen=$($LFS getstripe -g $file1)
17086         [[ $gen1 != $gen ]] ||
17087                 "Layout generation on $file1 does not change"
17088         gen=$($LFS getstripe -g $file2)
17089         [[ $gen2 != $gen ]] ||
17090                 "Layout generation on $file2 does not change"
17091
17092         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17093         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17094
17095         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17096 }
17097 run_test 184a "Basic layout swap"
17098
17099 test_184b() {
17100         check_swap_layouts_support
17101
17102         dir0=$DIR/$tdir/$testnum
17103         mkdir -p $dir0 || error "creating dir $dir0"
17104         file1=$dir0/f1
17105         file2=$dir0/f2
17106         file3=$dir0/f3
17107         dir1=$dir0/d1
17108         dir2=$dir0/d2
17109         mkdir $dir1 $dir2
17110         $LFS setstripe -c1 $file1
17111         $LFS setstripe -c2 $file2
17112         $LFS setstripe -c1 $file3
17113         chown $RUNAS_ID $file3
17114         gen1=$($LFS getstripe -g $file1)
17115         gen2=$($LFS getstripe -g $file2)
17116
17117         $LFS swap_layouts $dir1 $dir2 &&
17118                 error "swap of directories layouts should fail"
17119         $LFS swap_layouts $dir1 $file1 &&
17120                 error "swap of directory and file layouts should fail"
17121         $RUNAS $LFS swap_layouts $file1 $file2 &&
17122                 error "swap of file we cannot write should fail"
17123         $LFS swap_layouts $file1 $file3 &&
17124                 error "swap of file with different owner should fail"
17125         /bin/true # to clear error code
17126 }
17127 run_test 184b "Forbidden layout swap (will generate errors)"
17128
17129 test_184c() {
17130         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17131         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17132         check_swap_layouts_support
17133         check_swap_layout_no_dom $DIR
17134
17135         local dir0=$DIR/$tdir/$testnum
17136         mkdir -p $dir0 || error "creating dir $dir0"
17137
17138         local ref1=$dir0/ref1
17139         local ref2=$dir0/ref2
17140         local file1=$dir0/file1
17141         local file2=$dir0/file2
17142         # create a file large enough for the concurrent test
17143         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17144         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17145         echo "ref file size: ref1($(stat -c %s $ref1))," \
17146              "ref2($(stat -c %s $ref2))"
17147
17148         cp $ref2 $file2
17149         dd if=$ref1 of=$file1 bs=16k &
17150         local DD_PID=$!
17151
17152         # Make sure dd starts to copy file, but wait at most 5 seconds
17153         local loops=0
17154         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17155
17156         $LFS swap_layouts $file1 $file2
17157         local rc=$?
17158         wait $DD_PID
17159         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17160         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17161
17162         # how many bytes copied before swapping layout
17163         local copied=$(stat -c %s $file2)
17164         local remaining=$(stat -c %s $ref1)
17165         remaining=$((remaining - copied))
17166         echo "Copied $copied bytes before swapping layout..."
17167
17168         cmp -n $copied $file1 $ref2 | grep differ &&
17169                 error "Content mismatch [0, $copied) of ref2 and file1"
17170         cmp -n $copied $file2 $ref1 ||
17171                 error "Content mismatch [0, $copied) of ref1 and file2"
17172         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17173                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17174
17175         # clean up
17176         rm -f $ref1 $ref2 $file1 $file2
17177 }
17178 run_test 184c "Concurrent write and layout swap"
17179
17180 test_184d() {
17181         check_swap_layouts_support
17182         check_swap_layout_no_dom $DIR
17183         [ -z "$(which getfattr 2>/dev/null)" ] &&
17184                 skip_env "no getfattr command"
17185
17186         local file1=$DIR/$tdir/$tfile-1
17187         local file2=$DIR/$tdir/$tfile-2
17188         local file3=$DIR/$tdir/$tfile-3
17189         local lovea1
17190         local lovea2
17191
17192         mkdir -p $DIR/$tdir
17193         touch $file1 || error "create $file1 failed"
17194         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17195                 error "create $file2 failed"
17196         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17197                 error "create $file3 failed"
17198         lovea1=$(get_layout_param $file1)
17199
17200         $LFS swap_layouts $file2 $file3 ||
17201                 error "swap $file2 $file3 layouts failed"
17202         $LFS swap_layouts $file1 $file2 ||
17203                 error "swap $file1 $file2 layouts failed"
17204
17205         lovea2=$(get_layout_param $file2)
17206         echo "$lovea1"
17207         echo "$lovea2"
17208         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17209
17210         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17211         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17212 }
17213 run_test 184d "allow stripeless layouts swap"
17214
17215 test_184e() {
17216         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17217                 skip "Need MDS version at least 2.6.94"
17218         check_swap_layouts_support
17219         check_swap_layout_no_dom $DIR
17220         [ -z "$(which getfattr 2>/dev/null)" ] &&
17221                 skip_env "no getfattr command"
17222
17223         local file1=$DIR/$tdir/$tfile-1
17224         local file2=$DIR/$tdir/$tfile-2
17225         local file3=$DIR/$tdir/$tfile-3
17226         local lovea
17227
17228         mkdir -p $DIR/$tdir
17229         touch $file1 || error "create $file1 failed"
17230         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17231                 error "create $file2 failed"
17232         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17233                 error "create $file3 failed"
17234
17235         $LFS swap_layouts $file1 $file2 ||
17236                 error "swap $file1 $file2 layouts failed"
17237
17238         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17239         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17240
17241         echo 123 > $file1 || error "Should be able to write into $file1"
17242
17243         $LFS swap_layouts $file1 $file3 ||
17244                 error "swap $file1 $file3 layouts failed"
17245
17246         echo 123 > $file1 || error "Should be able to write into $file1"
17247
17248         rm -rf $file1 $file2 $file3
17249 }
17250 run_test 184e "Recreate layout after stripeless layout swaps"
17251
17252 test_184f() {
17253         # Create a file with name longer than sizeof(struct stat) ==
17254         # 144 to see if we can get chars from the file name to appear
17255         # in the returned striping. Note that 'f' == 0x66.
17256         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17257
17258         mkdir -p $DIR/$tdir
17259         mcreate $DIR/$tdir/$file
17260         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17261                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17262         fi
17263 }
17264 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17265
17266 test_185() { # LU-2441
17267         # LU-3553 - no volatile file support in old servers
17268         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17269                 skip "Need MDS version at least 2.3.60"
17270
17271         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17272         touch $DIR/$tdir/spoo
17273         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17274         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17275                 error "cannot create/write a volatile file"
17276         [ "$FILESET" == "" ] &&
17277         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17278                 error "FID is still valid after close"
17279
17280         multiop_bg_pause $DIR/$tdir vVw4096_c
17281         local multi_pid=$!
17282
17283         local OLD_IFS=$IFS
17284         IFS=":"
17285         local fidv=($fid)
17286         IFS=$OLD_IFS
17287         # assume that the next FID for this client is sequential, since stdout
17288         # is unfortunately eaten by multiop_bg_pause
17289         local n=$((${fidv[1]} + 1))
17290         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17291         if [ "$FILESET" == "" ]; then
17292                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17293                         error "FID is missing before close"
17294         fi
17295         kill -USR1 $multi_pid
17296         # 1 second delay, so if mtime change we will see it
17297         sleep 1
17298         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17299         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17300 }
17301 run_test 185 "Volatile file support"
17302
17303 function create_check_volatile() {
17304         local idx=$1
17305         local tgt
17306
17307         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17308         local PID=$!
17309         sleep 1
17310         local FID=$(cat /tmp/${tfile}.fid)
17311         [ "$FID" == "" ] && error "can't get FID for volatile"
17312         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17313         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17314         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17315         kill -USR1 $PID
17316         wait
17317         sleep 1
17318         cancel_lru_locks mdc # flush opencache
17319         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17320         return 0
17321 }
17322
17323 test_185a(){
17324         # LU-12516 - volatile creation via .lustre
17325         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17326                 skip "Need MDS version at least 2.3.55"
17327
17328         create_check_volatile 0
17329         [ $MDSCOUNT -lt 2 ] && return 0
17330
17331         # DNE case
17332         create_check_volatile 1
17333
17334         return 0
17335 }
17336 run_test 185a "Volatile file creation in .lustre/fid/"
17337
17338 test_187a() {
17339         remote_mds_nodsh && skip "remote MDS with nodsh"
17340         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17341                 skip "Need MDS version at least 2.3.0"
17342
17343         local dir0=$DIR/$tdir/$testnum
17344         mkdir -p $dir0 || error "creating dir $dir0"
17345
17346         local file=$dir0/file1
17347         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17348         local dv1=$($LFS data_version $file)
17349         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17350         local dv2=$($LFS data_version $file)
17351         [[ $dv1 != $dv2 ]] ||
17352                 error "data version did not change on write $dv1 == $dv2"
17353
17354         # clean up
17355         rm -f $file1
17356 }
17357 run_test 187a "Test data version change"
17358
17359 test_187b() {
17360         remote_mds_nodsh && skip "remote MDS with nodsh"
17361         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17362                 skip "Need MDS version at least 2.3.0"
17363
17364         local dir0=$DIR/$tdir/$testnum
17365         mkdir -p $dir0 || error "creating dir $dir0"
17366
17367         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17368         [[ ${DV[0]} != ${DV[1]} ]] ||
17369                 error "data version did not change on write"\
17370                       " ${DV[0]} == ${DV[1]}"
17371
17372         # clean up
17373         rm -f $file1
17374 }
17375 run_test 187b "Test data version change on volatile file"
17376
17377 test_200() {
17378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17379         remote_mgs_nodsh && skip "remote MGS with nodsh"
17380         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17381
17382         local POOL=${POOL:-cea1}
17383         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17384         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17385         # Pool OST targets
17386         local first_ost=0
17387         local last_ost=$(($OSTCOUNT - 1))
17388         local ost_step=2
17389         local ost_list=$(seq $first_ost $ost_step $last_ost)
17390         local ost_range="$first_ost $last_ost $ost_step"
17391         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17392         local file_dir=$POOL_ROOT/file_tst
17393         local subdir=$test_path/subdir
17394         local rc=0
17395
17396         while : ; do
17397                 # former test_200a test_200b
17398                 pool_add $POOL                          || { rc=$? ; break; }
17399                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17400                 # former test_200c test_200d
17401                 mkdir -p $test_path
17402                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17403                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17404                 mkdir -p $subdir
17405                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17406                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17407                                                         || { rc=$? ; break; }
17408                 # former test_200e test_200f
17409                 local files=$((OSTCOUNT*3))
17410                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17411                                                         || { rc=$? ; break; }
17412                 pool_create_files $POOL $file_dir $files "$ost_list" \
17413                                                         || { rc=$? ; break; }
17414                 # former test_200g test_200h
17415                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17416                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17417
17418                 # former test_201a test_201b test_201c
17419                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17420
17421                 local f=$test_path/$tfile
17422                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17423                 pool_remove $POOL $f                    || { rc=$? ; break; }
17424                 break
17425         done
17426
17427         destroy_test_pools
17428
17429         return $rc
17430 }
17431 run_test 200 "OST pools"
17432
17433 # usage: default_attr <count | size | offset>
17434 default_attr() {
17435         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17436 }
17437
17438 # usage: check_default_stripe_attr
17439 check_default_stripe_attr() {
17440         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17441         case $1 in
17442         --stripe-count|-c)
17443                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17444         --stripe-size|-S)
17445                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17446         --stripe-index|-i)
17447                 EXPECTED=-1;;
17448         *)
17449                 error "unknown getstripe attr '$1'"
17450         esac
17451
17452         [ $ACTUAL == $EXPECTED ] ||
17453                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17454 }
17455
17456 test_204a() {
17457         test_mkdir $DIR/$tdir
17458         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17459
17460         check_default_stripe_attr --stripe-count
17461         check_default_stripe_attr --stripe-size
17462         check_default_stripe_attr --stripe-index
17463 }
17464 run_test 204a "Print default stripe attributes"
17465
17466 test_204b() {
17467         test_mkdir $DIR/$tdir
17468         $LFS setstripe --stripe-count 1 $DIR/$tdir
17469
17470         check_default_stripe_attr --stripe-size
17471         check_default_stripe_attr --stripe-index
17472 }
17473 run_test 204b "Print default stripe size and offset"
17474
17475 test_204c() {
17476         test_mkdir $DIR/$tdir
17477         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17478
17479         check_default_stripe_attr --stripe-count
17480         check_default_stripe_attr --stripe-index
17481 }
17482 run_test 204c "Print default stripe count and offset"
17483
17484 test_204d() {
17485         test_mkdir $DIR/$tdir
17486         $LFS setstripe --stripe-index 0 $DIR/$tdir
17487
17488         check_default_stripe_attr --stripe-count
17489         check_default_stripe_attr --stripe-size
17490 }
17491 run_test 204d "Print default stripe count and size"
17492
17493 test_204e() {
17494         test_mkdir $DIR/$tdir
17495         $LFS setstripe -d $DIR/$tdir
17496
17497         check_default_stripe_attr --stripe-count --raw
17498         check_default_stripe_attr --stripe-size --raw
17499         check_default_stripe_attr --stripe-index --raw
17500 }
17501 run_test 204e "Print raw stripe attributes"
17502
17503 test_204f() {
17504         test_mkdir $DIR/$tdir
17505         $LFS setstripe --stripe-count 1 $DIR/$tdir
17506
17507         check_default_stripe_attr --stripe-size --raw
17508         check_default_stripe_attr --stripe-index --raw
17509 }
17510 run_test 204f "Print raw stripe size and offset"
17511
17512 test_204g() {
17513         test_mkdir $DIR/$tdir
17514         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17515
17516         check_default_stripe_attr --stripe-count --raw
17517         check_default_stripe_attr --stripe-index --raw
17518 }
17519 run_test 204g "Print raw stripe count and offset"
17520
17521 test_204h() {
17522         test_mkdir $DIR/$tdir
17523         $LFS setstripe --stripe-index 0 $DIR/$tdir
17524
17525         check_default_stripe_attr --stripe-count --raw
17526         check_default_stripe_attr --stripe-size --raw
17527 }
17528 run_test 204h "Print raw stripe count and size"
17529
17530 # Figure out which job scheduler is being used, if any,
17531 # or use a fake one
17532 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17533         JOBENV=SLURM_JOB_ID
17534 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17535         JOBENV=LSB_JOBID
17536 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17537         JOBENV=PBS_JOBID
17538 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17539         JOBENV=LOADL_STEP_ID
17540 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17541         JOBENV=JOB_ID
17542 else
17543         $LCTL list_param jobid_name > /dev/null 2>&1
17544         if [ $? -eq 0 ]; then
17545                 JOBENV=nodelocal
17546         else
17547                 JOBENV=FAKE_JOBID
17548         fi
17549 fi
17550 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17551
17552 verify_jobstats() {
17553         local cmd=($1)
17554         shift
17555         local facets="$@"
17556
17557 # we don't really need to clear the stats for this test to work, since each
17558 # command has a unique jobid, but it makes debugging easier if needed.
17559 #       for facet in $facets; do
17560 #               local dev=$(convert_facet2label $facet)
17561 #               # clear old jobstats
17562 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17563 #       done
17564
17565         # use a new JobID for each test, or we might see an old one
17566         [ "$JOBENV" = "FAKE_JOBID" ] &&
17567                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17568
17569         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17570
17571         [ "$JOBENV" = "nodelocal" ] && {
17572                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17573                 $LCTL set_param jobid_name=$FAKE_JOBID
17574                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17575         }
17576
17577         log "Test: ${cmd[*]}"
17578         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17579
17580         if [ $JOBENV = "FAKE_JOBID" ]; then
17581                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17582         else
17583                 ${cmd[*]}
17584         fi
17585
17586         # all files are created on OST0000
17587         for facet in $facets; do
17588                 local stats="*.$(convert_facet2label $facet).job_stats"
17589
17590                 # strip out libtool wrappers for in-tree executables
17591                 if [ $(do_facet $facet lctl get_param $stats |
17592                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17593                         do_facet $facet lctl get_param $stats
17594                         error "No jobstats for $JOBVAL found on $facet::$stats"
17595                 fi
17596         done
17597 }
17598
17599 jobstats_set() {
17600         local new_jobenv=$1
17601
17602         set_persistent_param_and_check client "jobid_var" \
17603                 "$FSNAME.sys.jobid_var" $new_jobenv
17604 }
17605
17606 test_205a() { # Job stats
17607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17608         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17609                 skip "Need MDS version with at least 2.7.1"
17610         remote_mgs_nodsh && skip "remote MGS with nodsh"
17611         remote_mds_nodsh && skip "remote MDS with nodsh"
17612         remote_ost_nodsh && skip "remote OST with nodsh"
17613         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17614                 skip "Server doesn't support jobstats"
17615         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17616
17617         local old_jobenv=$($LCTL get_param -n jobid_var)
17618         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17619
17620         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17621                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17622         else
17623                 stack_trap "do_facet mgs $PERM_CMD \
17624                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17625         fi
17626         changelog_register
17627
17628         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17629                                 mdt.*.job_cleanup_interval | head -n 1)
17630         local new_interval=5
17631         do_facet $SINGLEMDS \
17632                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17633         stack_trap "do_facet $SINGLEMDS \
17634                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17635         local start=$SECONDS
17636
17637         local cmd
17638         # mkdir
17639         cmd="mkdir $DIR/$tdir"
17640         verify_jobstats "$cmd" "$SINGLEMDS"
17641         # rmdir
17642         cmd="rmdir $DIR/$tdir"
17643         verify_jobstats "$cmd" "$SINGLEMDS"
17644         # mkdir on secondary MDT
17645         if [ $MDSCOUNT -gt 1 ]; then
17646                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17647                 verify_jobstats "$cmd" "mds2"
17648         fi
17649         # mknod
17650         cmd="mknod $DIR/$tfile c 1 3"
17651         verify_jobstats "$cmd" "$SINGLEMDS"
17652         # unlink
17653         cmd="rm -f $DIR/$tfile"
17654         verify_jobstats "$cmd" "$SINGLEMDS"
17655         # create all files on OST0000 so verify_jobstats can find OST stats
17656         # open & close
17657         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17658         verify_jobstats "$cmd" "$SINGLEMDS"
17659         # setattr
17660         cmd="touch $DIR/$tfile"
17661         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17662         # write
17663         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17664         verify_jobstats "$cmd" "ost1"
17665         # read
17666         cancel_lru_locks osc
17667         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17668         verify_jobstats "$cmd" "ost1"
17669         # truncate
17670         cmd="$TRUNCATE $DIR/$tfile 0"
17671         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17672         # rename
17673         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17674         verify_jobstats "$cmd" "$SINGLEMDS"
17675         # jobstats expiry - sleep until old stats should be expired
17676         local left=$((new_interval + 5 - (SECONDS - start)))
17677         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17678                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17679                         "0" $left
17680         cmd="mkdir $DIR/$tdir.expire"
17681         verify_jobstats "$cmd" "$SINGLEMDS"
17682         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17683             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17684
17685         # Ensure that jobid are present in changelog (if supported by MDS)
17686         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17687                 changelog_dump | tail -10
17688                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17689                 [ $jobids -eq 9 ] ||
17690                         error "Wrong changelog jobid count $jobids != 9"
17691
17692                 # LU-5862
17693                 JOBENV="disable"
17694                 jobstats_set $JOBENV
17695                 touch $DIR/$tfile
17696                 changelog_dump | grep $tfile
17697                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17698                 [ $jobids -eq 0 ] ||
17699                         error "Unexpected jobids when jobid_var=$JOBENV"
17700         fi
17701
17702         # test '%j' access to environment variable - if supported
17703         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17704                 JOBENV="JOBCOMPLEX"
17705                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17706
17707                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17708         fi
17709
17710         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17711                 JOBENV="JOBCOMPLEX"
17712                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17713
17714                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17715         fi
17716
17717         # test '%j' access to per-session jobid - if supported
17718         if lctl list_param jobid_this_session > /dev/null 2>&1
17719         then
17720                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17721                 lctl set_param jobid_this_session=$USER
17722
17723                 JOBENV="JOBCOMPLEX"
17724                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17725
17726                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17727         fi
17728 }
17729 run_test 205a "Verify job stats"
17730
17731 # LU-13117, LU-13597
17732 test_205b() {
17733         job_stats="mdt.*.job_stats"
17734         $LCTL set_param $job_stats=clear
17735         # Setting jobid_var to USER might not be supported
17736         $LCTL set_param jobid_var=USER || true
17737         $LCTL set_param jobid_name="%e.%u"
17738         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17739         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17740                 grep "job_id:.*foolish" &&
17741                         error "Unexpected jobid found"
17742         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17743                 grep "open:.*min.*max.*sum" ||
17744                         error "wrong job_stats format found"
17745 }
17746 run_test 205b "Verify job stats jobid and output format"
17747
17748 # LU-13733
17749 test_205c() {
17750         $LCTL set_param llite.*.stats=0
17751         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17752         $LCTL get_param llite.*.stats
17753         $LCTL get_param llite.*.stats | grep \
17754                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17755                         error "wrong client stats format found"
17756 }
17757 run_test 205c "Verify client stats format"
17758
17759 # LU-1480, LU-1773 and LU-1657
17760 test_206() {
17761         mkdir -p $DIR/$tdir
17762         $LFS setstripe -c -1 $DIR/$tdir
17763 #define OBD_FAIL_LOV_INIT 0x1403
17764         $LCTL set_param fail_loc=0xa0001403
17765         $LCTL set_param fail_val=1
17766         touch $DIR/$tdir/$tfile || true
17767 }
17768 run_test 206 "fail lov_init_raid0() doesn't lbug"
17769
17770 test_207a() {
17771         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17772         local fsz=`stat -c %s $DIR/$tfile`
17773         cancel_lru_locks mdc
17774
17775         # do not return layout in getattr intent
17776 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17777         $LCTL set_param fail_loc=0x170
17778         local sz=`stat -c %s $DIR/$tfile`
17779
17780         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17781
17782         rm -rf $DIR/$tfile
17783 }
17784 run_test 207a "can refresh layout at glimpse"
17785
17786 test_207b() {
17787         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17788         local cksum=`md5sum $DIR/$tfile`
17789         local fsz=`stat -c %s $DIR/$tfile`
17790         cancel_lru_locks mdc
17791         cancel_lru_locks osc
17792
17793         # do not return layout in getattr intent
17794 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17795         $LCTL set_param fail_loc=0x171
17796
17797         # it will refresh layout after the file is opened but before read issues
17798         echo checksum is "$cksum"
17799         echo "$cksum" |md5sum -c --quiet || error "file differs"
17800
17801         rm -rf $DIR/$tfile
17802 }
17803 run_test 207b "can refresh layout at open"
17804
17805 test_208() {
17806         # FIXME: in this test suite, only RD lease is used. This is okay
17807         # for now as only exclusive open is supported. After generic lease
17808         # is done, this test suite should be revised. - Jinshan
17809
17810         remote_mds_nodsh && skip "remote MDS with nodsh"
17811         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17812                 skip "Need MDS version at least 2.4.52"
17813
17814         echo "==== test 1: verify get lease work"
17815         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17816
17817         echo "==== test 2: verify lease can be broken by upcoming open"
17818         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17819         local PID=$!
17820         sleep 1
17821
17822         $MULTIOP $DIR/$tfile oO_RDONLY:c
17823         kill -USR1 $PID && wait $PID || error "break lease error"
17824
17825         echo "==== test 3: verify lease can't be granted if an open already exists"
17826         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17827         local PID=$!
17828         sleep 1
17829
17830         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17831         kill -USR1 $PID && wait $PID || error "open file error"
17832
17833         echo "==== test 4: lease can sustain over recovery"
17834         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17835         PID=$!
17836         sleep 1
17837
17838         fail mds1
17839
17840         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17841
17842         echo "==== test 5: lease broken can't be regained by replay"
17843         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17844         PID=$!
17845         sleep 1
17846
17847         # open file to break lease and then recovery
17848         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17849         fail mds1
17850
17851         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17852
17853         rm -f $DIR/$tfile
17854 }
17855 run_test 208 "Exclusive open"
17856
17857 test_209() {
17858         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17859                 skip_env "must have disp_stripe"
17860
17861         touch $DIR/$tfile
17862         sync; sleep 5; sync;
17863
17864         echo 3 > /proc/sys/vm/drop_caches
17865         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17866                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17867         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17868
17869         # open/close 500 times
17870         for i in $(seq 500); do
17871                 cat $DIR/$tfile
17872         done
17873
17874         echo 3 > /proc/sys/vm/drop_caches
17875         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17876                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17877         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17878
17879         echo "before: $req_before, after: $req_after"
17880         [ $((req_after - req_before)) -ge 300 ] &&
17881                 error "open/close requests are not freed"
17882         return 0
17883 }
17884 run_test 209 "read-only open/close requests should be freed promptly"
17885
17886 test_210() {
17887         local pid
17888
17889         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17890         pid=$!
17891         sleep 1
17892
17893         $LFS getstripe $DIR/$tfile
17894         kill -USR1 $pid
17895         wait $pid || error "multiop failed"
17896
17897         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17898         pid=$!
17899         sleep 1
17900
17901         $LFS getstripe $DIR/$tfile
17902         kill -USR1 $pid
17903         wait $pid || error "multiop failed"
17904 }
17905 run_test 210 "lfs getstripe does not break leases"
17906
17907 test_212() {
17908         size=`date +%s`
17909         size=$((size % 8192 + 1))
17910         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17911         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17912         rm -f $DIR/f212 $DIR/f212.xyz
17913 }
17914 run_test 212 "Sendfile test ============================================"
17915
17916 test_213() {
17917         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17918         cancel_lru_locks osc
17919         lctl set_param fail_loc=0x8000040f
17920         # generate a read lock
17921         cat $DIR/$tfile > /dev/null
17922         # write to the file, it will try to cancel the above read lock.
17923         cat /etc/hosts >> $DIR/$tfile
17924 }
17925 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17926
17927 test_214() { # for bug 20133
17928         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17929         for (( i=0; i < 340; i++ )) ; do
17930                 touch $DIR/$tdir/d214c/a$i
17931         done
17932
17933         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17934         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17935         ls $DIR/d214c || error "ls $DIR/d214c failed"
17936         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17937         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17938 }
17939 run_test 214 "hash-indexed directory test - bug 20133"
17940
17941 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17942 create_lnet_proc_files() {
17943         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17944 }
17945
17946 # counterpart of create_lnet_proc_files
17947 remove_lnet_proc_files() {
17948         rm -f $TMP/lnet_$1.sys
17949 }
17950
17951 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17952 # 3rd arg as regexp for body
17953 check_lnet_proc_stats() {
17954         local l=$(cat "$TMP/lnet_$1" |wc -l)
17955         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17956
17957         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17958 }
17959
17960 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17961 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17962 # optional and can be regexp for 2nd line (lnet.routes case)
17963 check_lnet_proc_entry() {
17964         local blp=2          # blp stands for 'position of 1st line of body'
17965         [ -z "$5" ] || blp=3 # lnet.routes case
17966
17967         local l=$(cat "$TMP/lnet_$1" |wc -l)
17968         # subtracting one from $blp because the body can be empty
17969         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17970
17971         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17972                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17973
17974         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17975                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17976
17977         # bail out if any unexpected line happened
17978         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17979         [ "$?" != 0 ] || error "$2 misformatted"
17980 }
17981
17982 test_215() { # for bugs 18102, 21079, 21517
17983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17984
17985         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17986         local P='[1-9][0-9]*'           # positive numeric
17987         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17988         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17989         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17990         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17991
17992         local L1 # regexp for 1st line
17993         local L2 # regexp for 2nd line (optional)
17994         local BR # regexp for the rest (body)
17995
17996         # lnet.stats should look as 11 space-separated non-negative numerics
17997         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17998         create_lnet_proc_files "stats"
17999         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18000         remove_lnet_proc_files "stats"
18001
18002         # lnet.routes should look like this:
18003         # Routing disabled/enabled
18004         # net hops priority state router
18005         # where net is a string like tcp0, hops > 0, priority >= 0,
18006         # state is up/down,
18007         # router is a string like 192.168.1.1@tcp2
18008         L1="^Routing (disabled|enabled)$"
18009         L2="^net +hops +priority +state +router$"
18010         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18011         create_lnet_proc_files "routes"
18012         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18013         remove_lnet_proc_files "routes"
18014
18015         # lnet.routers should look like this:
18016         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18017         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18018         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18019         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18020         L1="^ref +rtr_ref +alive +router$"
18021         BR="^$P +$P +(up|down) +$NID$"
18022         create_lnet_proc_files "routers"
18023         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18024         remove_lnet_proc_files "routers"
18025
18026         # lnet.peers should look like this:
18027         # nid refs state last max rtr min tx min queue
18028         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18029         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18030         # numeric (0 or >0 or <0), queue >= 0.
18031         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18032         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18033         create_lnet_proc_files "peers"
18034         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18035         remove_lnet_proc_files "peers"
18036
18037         # lnet.buffers  should look like this:
18038         # pages count credits min
18039         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18040         L1="^pages +count +credits +min$"
18041         BR="^ +$N +$N +$I +$I$"
18042         create_lnet_proc_files "buffers"
18043         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18044         remove_lnet_proc_files "buffers"
18045
18046         # lnet.nis should look like this:
18047         # nid status alive refs peer rtr max tx min
18048         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18049         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18050         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18051         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18052         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18053         create_lnet_proc_files "nis"
18054         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18055         remove_lnet_proc_files "nis"
18056
18057         # can we successfully write to lnet.stats?
18058         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18059 }
18060 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18061
18062 test_216() { # bug 20317
18063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18064         remote_ost_nodsh && skip "remote OST with nodsh"
18065
18066         local node
18067         local facets=$(get_facets OST)
18068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18069
18070         save_lustre_params client "osc.*.contention_seconds" > $p
18071         save_lustre_params $facets \
18072                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18073         save_lustre_params $facets \
18074                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18075         save_lustre_params $facets \
18076                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18077         clear_stats osc.*.osc_stats
18078
18079         # agressive lockless i/o settings
18080         do_nodes $(comma_list $(osts_nodes)) \
18081                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18082                         ldlm.namespaces.filter-*.contended_locks=0 \
18083                         ldlm.namespaces.filter-*.contention_seconds=60"
18084         lctl set_param -n osc.*.contention_seconds=60
18085
18086         $DIRECTIO write $DIR/$tfile 0 10 4096
18087         $CHECKSTAT -s 40960 $DIR/$tfile
18088
18089         # disable lockless i/o
18090         do_nodes $(comma_list $(osts_nodes)) \
18091                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18092                         ldlm.namespaces.filter-*.contended_locks=32 \
18093                         ldlm.namespaces.filter-*.contention_seconds=0"
18094         lctl set_param -n osc.*.contention_seconds=0
18095         clear_stats osc.*.osc_stats
18096
18097         dd if=/dev/zero of=$DIR/$tfile count=0
18098         $CHECKSTAT -s 0 $DIR/$tfile
18099
18100         restore_lustre_params <$p
18101         rm -f $p
18102         rm $DIR/$tfile
18103 }
18104 run_test 216 "check lockless direct write updates file size and kms correctly"
18105
18106 test_217() { # bug 22430
18107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18108
18109         local node
18110         local nid
18111
18112         for node in $(nodes_list); do
18113                 nid=$(host_nids_address $node $NETTYPE)
18114                 if [[ $nid = *-* ]] ; then
18115                         echo "lctl ping $(h2nettype $nid)"
18116                         lctl ping $(h2nettype $nid)
18117                 else
18118                         echo "skipping $node (no hyphen detected)"
18119                 fi
18120         done
18121 }
18122 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18123
18124 test_218() {
18125        # do directio so as not to populate the page cache
18126        log "creating a 10 Mb file"
18127        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18128        log "starting reads"
18129        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18130        log "truncating the file"
18131        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18132        log "killing dd"
18133        kill %+ || true # reads might have finished
18134        echo "wait until dd is finished"
18135        wait
18136        log "removing the temporary file"
18137        rm -rf $DIR/$tfile || error "tmp file removal failed"
18138 }
18139 run_test 218 "parallel read and truncate should not deadlock"
18140
18141 test_219() {
18142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18143
18144         # write one partial page
18145         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18146         # set no grant so vvp_io_commit_write will do sync write
18147         $LCTL set_param fail_loc=0x411
18148         # write a full page at the end of file
18149         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18150
18151         $LCTL set_param fail_loc=0
18152         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18153         $LCTL set_param fail_loc=0x411
18154         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18155
18156         # LU-4201
18157         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18158         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18159 }
18160 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18161
18162 test_220() { #LU-325
18163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18164         remote_ost_nodsh && skip "remote OST with nodsh"
18165         remote_mds_nodsh && skip "remote MDS with nodsh"
18166         remote_mgs_nodsh && skip "remote MGS with nodsh"
18167
18168         local OSTIDX=0
18169
18170         # create on MDT0000 so the last_id and next_id are correct
18171         mkdir $DIR/$tdir
18172         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18173         OST=${OST%_UUID}
18174
18175         # on the mdt's osc
18176         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18177         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18178                         osp.$mdtosc_proc1.prealloc_last_id)
18179         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18180                         osp.$mdtosc_proc1.prealloc_next_id)
18181
18182         $LFS df -i
18183
18184         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18185         #define OBD_FAIL_OST_ENOINO              0x229
18186         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18187         create_pool $FSNAME.$TESTNAME || return 1
18188         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18189
18190         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18191
18192         MDSOBJS=$((last_id - next_id))
18193         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18194
18195         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18196         echo "OST still has $count kbytes free"
18197
18198         echo "create $MDSOBJS files @next_id..."
18199         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18200
18201         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18202                         osp.$mdtosc_proc1.prealloc_last_id)
18203         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18204                         osp.$mdtosc_proc1.prealloc_next_id)
18205
18206         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18207         $LFS df -i
18208
18209         echo "cleanup..."
18210
18211         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18212         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18213
18214         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18215                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18216         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18217                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18218         echo "unlink $MDSOBJS files @$next_id..."
18219         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18220 }
18221 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18222
18223 test_221() {
18224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18225
18226         dd if=`which date` of=$MOUNT/date oflag=sync
18227         chmod +x $MOUNT/date
18228
18229         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18230         $LCTL set_param fail_loc=0x80001401
18231
18232         $MOUNT/date > /dev/null
18233         rm -f $MOUNT/date
18234 }
18235 run_test 221 "make sure fault and truncate race to not cause OOM"
18236
18237 test_222a () {
18238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18239
18240         rm -rf $DIR/$tdir
18241         test_mkdir $DIR/$tdir
18242         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18243         createmany -o $DIR/$tdir/$tfile 10
18244         cancel_lru_locks mdc
18245         cancel_lru_locks osc
18246         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18247         $LCTL set_param fail_loc=0x31a
18248         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18249         $LCTL set_param fail_loc=0
18250         rm -r $DIR/$tdir
18251 }
18252 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18253
18254 test_222b () {
18255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18256
18257         rm -rf $DIR/$tdir
18258         test_mkdir $DIR/$tdir
18259         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18260         createmany -o $DIR/$tdir/$tfile 10
18261         cancel_lru_locks mdc
18262         cancel_lru_locks osc
18263         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18264         $LCTL set_param fail_loc=0x31a
18265         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18266         $LCTL set_param fail_loc=0
18267 }
18268 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18269
18270 test_223 () {
18271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18272
18273         rm -rf $DIR/$tdir
18274         test_mkdir $DIR/$tdir
18275         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18276         createmany -o $DIR/$tdir/$tfile 10
18277         cancel_lru_locks mdc
18278         cancel_lru_locks osc
18279         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18280         $LCTL set_param fail_loc=0x31b
18281         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18282         $LCTL set_param fail_loc=0
18283         rm -r $DIR/$tdir
18284 }
18285 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18286
18287 test_224a() { # LU-1039, MRP-303
18288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18289
18290         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18291         $LCTL set_param fail_loc=0x508
18292         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18293         $LCTL set_param fail_loc=0
18294         df $DIR
18295 }
18296 run_test 224a "Don't panic on bulk IO failure"
18297
18298 test_224b() { # LU-1039, MRP-303
18299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18300
18301         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18302         cancel_lru_locks osc
18303         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18304         $LCTL set_param fail_loc=0x515
18305         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18306         $LCTL set_param fail_loc=0
18307         df $DIR
18308 }
18309 run_test 224b "Don't panic on bulk IO failure"
18310
18311 test_224c() { # LU-6441
18312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18313         remote_mds_nodsh && skip "remote MDS with nodsh"
18314
18315         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18316         save_writethrough $p
18317         set_cache writethrough on
18318
18319         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18320         local at_max=$($LCTL get_param -n at_max)
18321         local timeout=$($LCTL get_param -n timeout)
18322         local test_at="at_max"
18323         local param_at="$FSNAME.sys.at_max"
18324         local test_timeout="timeout"
18325         local param_timeout="$FSNAME.sys.timeout"
18326
18327         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18328
18329         set_persistent_param_and_check client "$test_at" "$param_at" 0
18330         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18331
18332         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18333         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18334         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18335         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18336         sync
18337         do_facet ost1 "$LCTL set_param fail_loc=0"
18338
18339         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18340         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18341                 $timeout
18342
18343         $LCTL set_param -n $pages_per_rpc
18344         restore_lustre_params < $p
18345         rm -f $p
18346 }
18347 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18348
18349 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18350 test_225a () {
18351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18352         if [ -z ${MDSSURVEY} ]; then
18353                 skip_env "mds-survey not found"
18354         fi
18355         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18356                 skip "Need MDS version at least 2.2.51"
18357
18358         local mds=$(facet_host $SINGLEMDS)
18359         local target=$(do_nodes $mds 'lctl dl' |
18360                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18361
18362         local cmd1="file_count=1000 thrhi=4"
18363         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18364         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18365         local cmd="$cmd1 $cmd2 $cmd3"
18366
18367         rm -f ${TMP}/mds_survey*
18368         echo + $cmd
18369         eval $cmd || error "mds-survey with zero-stripe failed"
18370         cat ${TMP}/mds_survey*
18371         rm -f ${TMP}/mds_survey*
18372 }
18373 run_test 225a "Metadata survey sanity with zero-stripe"
18374
18375 test_225b () {
18376         if [ -z ${MDSSURVEY} ]; then
18377                 skip_env "mds-survey not found"
18378         fi
18379         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18380                 skip "Need MDS version at least 2.2.51"
18381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18382         remote_mds_nodsh && skip "remote MDS with nodsh"
18383         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18384                 skip_env "Need to mount OST to test"
18385         fi
18386
18387         local mds=$(facet_host $SINGLEMDS)
18388         local target=$(do_nodes $mds 'lctl dl' |
18389                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18390
18391         local cmd1="file_count=1000 thrhi=4"
18392         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18393         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18394         local cmd="$cmd1 $cmd2 $cmd3"
18395
18396         rm -f ${TMP}/mds_survey*
18397         echo + $cmd
18398         eval $cmd || error "mds-survey with stripe_count failed"
18399         cat ${TMP}/mds_survey*
18400         rm -f ${TMP}/mds_survey*
18401 }
18402 run_test 225b "Metadata survey sanity with stripe_count = 1"
18403
18404 mcreate_path2fid () {
18405         local mode=$1
18406         local major=$2
18407         local minor=$3
18408         local name=$4
18409         local desc=$5
18410         local path=$DIR/$tdir/$name
18411         local fid
18412         local rc
18413         local fid_path
18414
18415         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18416                 error "cannot create $desc"
18417
18418         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18419         rc=$?
18420         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18421
18422         fid_path=$($LFS fid2path $MOUNT $fid)
18423         rc=$?
18424         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18425
18426         [ "$path" == "$fid_path" ] ||
18427                 error "fid2path returned $fid_path, expected $path"
18428
18429         echo "pass with $path and $fid"
18430 }
18431
18432 test_226a () {
18433         rm -rf $DIR/$tdir
18434         mkdir -p $DIR/$tdir
18435
18436         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18437         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18438         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18439         mcreate_path2fid 0040666 0 0 dir "directory"
18440         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18441         mcreate_path2fid 0100666 0 0 file "regular file"
18442         mcreate_path2fid 0120666 0 0 link "symbolic link"
18443         mcreate_path2fid 0140666 0 0 sock "socket"
18444 }
18445 run_test 226a "call path2fid and fid2path on files of all type"
18446
18447 test_226b () {
18448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18449
18450         local MDTIDX=1
18451
18452         rm -rf $DIR/$tdir
18453         mkdir -p $DIR/$tdir
18454         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18455                 error "create remote directory failed"
18456         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18457         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18458                                 "character special file (null)"
18459         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18460                                 "character special file (no device)"
18461         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18462         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18463                                 "block special file (loop)"
18464         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18465         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18466         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18467 }
18468 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18469
18470 test_226c () {
18471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18472         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18473                 skip "Need MDS version at least 2.13.55"
18474
18475         local submnt=/mnt/submnt
18476         local srcfile=/etc/passwd
18477         local dstfile=$submnt/passwd
18478         local path
18479         local fid
18480
18481         rm -rf $DIR/$tdir
18482         rm -rf $submnt
18483         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18484                 error "create remote directory failed"
18485         mkdir -p $submnt || error "create $submnt failed"
18486         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18487                 error "mount $submnt failed"
18488         stack_trap "umount $submnt" EXIT
18489
18490         cp $srcfile $dstfile
18491         fid=$($LFS path2fid $dstfile)
18492         path=$($LFS fid2path $submnt "$fid")
18493         [ "$path" = "$dstfile" ] ||
18494                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18495 }
18496 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18497
18498 # LU-1299 Executing or running ldd on a truncated executable does not
18499 # cause an out-of-memory condition.
18500 test_227() {
18501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18502         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18503
18504         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18505         chmod +x $MOUNT/date
18506
18507         $MOUNT/date > /dev/null
18508         ldd $MOUNT/date > /dev/null
18509         rm -f $MOUNT/date
18510 }
18511 run_test 227 "running truncated executable does not cause OOM"
18512
18513 # LU-1512 try to reuse idle OI blocks
18514 test_228a() {
18515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18516         remote_mds_nodsh && skip "remote MDS with nodsh"
18517         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18518
18519         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18520         local myDIR=$DIR/$tdir
18521
18522         mkdir -p $myDIR
18523         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18524         $LCTL set_param fail_loc=0x80001002
18525         createmany -o $myDIR/t- 10000
18526         $LCTL set_param fail_loc=0
18527         # The guard is current the largest FID holder
18528         touch $myDIR/guard
18529         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18530                     tr -d '[')
18531         local IDX=$(($SEQ % 64))
18532
18533         do_facet $SINGLEMDS sync
18534         # Make sure journal flushed.
18535         sleep 6
18536         local blk1=$(do_facet $SINGLEMDS \
18537                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18538                      grep Blockcount | awk '{print $4}')
18539
18540         # Remove old files, some OI blocks will become idle.
18541         unlinkmany $myDIR/t- 10000
18542         # Create new files, idle OI blocks should be reused.
18543         createmany -o $myDIR/t- 2000
18544         do_facet $SINGLEMDS sync
18545         # Make sure journal flushed.
18546         sleep 6
18547         local blk2=$(do_facet $SINGLEMDS \
18548                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18549                      grep Blockcount | awk '{print $4}')
18550
18551         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18552 }
18553 run_test 228a "try to reuse idle OI blocks"
18554
18555 test_228b() {
18556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18557         remote_mds_nodsh && skip "remote MDS with nodsh"
18558         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18559
18560         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18561         local myDIR=$DIR/$tdir
18562
18563         mkdir -p $myDIR
18564         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18565         $LCTL set_param fail_loc=0x80001002
18566         createmany -o $myDIR/t- 10000
18567         $LCTL set_param fail_loc=0
18568         # The guard is current the largest FID holder
18569         touch $myDIR/guard
18570         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18571                     tr -d '[')
18572         local IDX=$(($SEQ % 64))
18573
18574         do_facet $SINGLEMDS sync
18575         # Make sure journal flushed.
18576         sleep 6
18577         local blk1=$(do_facet $SINGLEMDS \
18578                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18579                      grep Blockcount | awk '{print $4}')
18580
18581         # Remove old files, some OI blocks will become idle.
18582         unlinkmany $myDIR/t- 10000
18583
18584         # stop the MDT
18585         stop $SINGLEMDS || error "Fail to stop MDT."
18586         # remount the MDT
18587         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18588
18589         df $MOUNT || error "Fail to df."
18590         # Create new files, idle OI blocks should be reused.
18591         createmany -o $myDIR/t- 2000
18592         do_facet $SINGLEMDS sync
18593         # Make sure journal flushed.
18594         sleep 6
18595         local blk2=$(do_facet $SINGLEMDS \
18596                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18597                      grep Blockcount | awk '{print $4}')
18598
18599         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18600 }
18601 run_test 228b "idle OI blocks can be reused after MDT restart"
18602
18603 #LU-1881
18604 test_228c() {
18605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18606         remote_mds_nodsh && skip "remote MDS with nodsh"
18607         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18608
18609         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18610         local myDIR=$DIR/$tdir
18611
18612         mkdir -p $myDIR
18613         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18614         $LCTL set_param fail_loc=0x80001002
18615         # 20000 files can guarantee there are index nodes in the OI file
18616         createmany -o $myDIR/t- 20000
18617         $LCTL set_param fail_loc=0
18618         # The guard is current the largest FID holder
18619         touch $myDIR/guard
18620         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18621                     tr -d '[')
18622         local IDX=$(($SEQ % 64))
18623
18624         do_facet $SINGLEMDS sync
18625         # Make sure journal flushed.
18626         sleep 6
18627         local blk1=$(do_facet $SINGLEMDS \
18628                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18629                      grep Blockcount | awk '{print $4}')
18630
18631         # Remove old files, some OI blocks will become idle.
18632         unlinkmany $myDIR/t- 20000
18633         rm -f $myDIR/guard
18634         # The OI file should become empty now
18635
18636         # Create new files, idle OI blocks should be reused.
18637         createmany -o $myDIR/t- 2000
18638         do_facet $SINGLEMDS sync
18639         # Make sure journal flushed.
18640         sleep 6
18641         local blk2=$(do_facet $SINGLEMDS \
18642                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18643                      grep Blockcount | awk '{print $4}')
18644
18645         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18646 }
18647 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18648
18649 test_229() { # LU-2482, LU-3448
18650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18651         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18652         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18653                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18654
18655         rm -f $DIR/$tfile
18656
18657         # Create a file with a released layout and stripe count 2.
18658         $MULTIOP $DIR/$tfile H2c ||
18659                 error "failed to create file with released layout"
18660
18661         $LFS getstripe -v $DIR/$tfile
18662
18663         local pattern=$($LFS getstripe -L $DIR/$tfile)
18664         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18665
18666         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18667                 error "getstripe"
18668         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18669         stat $DIR/$tfile || error "failed to stat released file"
18670
18671         chown $RUNAS_ID $DIR/$tfile ||
18672                 error "chown $RUNAS_ID $DIR/$tfile failed"
18673
18674         chgrp $RUNAS_ID $DIR/$tfile ||
18675                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18676
18677         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18678         rm $DIR/$tfile || error "failed to remove released file"
18679 }
18680 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18681
18682 test_230a() {
18683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18685         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18686                 skip "Need MDS version at least 2.11.52"
18687
18688         local MDTIDX=1
18689
18690         test_mkdir $DIR/$tdir
18691         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18692         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18693         [ $mdt_idx -ne 0 ] &&
18694                 error "create local directory on wrong MDT $mdt_idx"
18695
18696         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18697                         error "create remote directory failed"
18698         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18699         [ $mdt_idx -ne $MDTIDX ] &&
18700                 error "create remote directory on wrong MDT $mdt_idx"
18701
18702         createmany -o $DIR/$tdir/test_230/t- 10 ||
18703                 error "create files on remote directory failed"
18704         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18705         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18706         rm -r $DIR/$tdir || error "unlink remote directory failed"
18707 }
18708 run_test 230a "Create remote directory and files under the remote directory"
18709
18710 test_230b() {
18711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18713         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18714                 skip "Need MDS version at least 2.11.52"
18715
18716         local MDTIDX=1
18717         local mdt_index
18718         local i
18719         local file
18720         local pid
18721         local stripe_count
18722         local migrate_dir=$DIR/$tdir/migrate_dir
18723         local other_dir=$DIR/$tdir/other_dir
18724
18725         test_mkdir $DIR/$tdir
18726         test_mkdir -i0 -c1 $migrate_dir
18727         test_mkdir -i0 -c1 $other_dir
18728         for ((i=0; i<10; i++)); do
18729                 mkdir -p $migrate_dir/dir_${i}
18730                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18731                         error "create files under remote dir failed $i"
18732         done
18733
18734         cp /etc/passwd $migrate_dir/$tfile
18735         cp /etc/passwd $other_dir/$tfile
18736         chattr +SAD $migrate_dir
18737         chattr +SAD $migrate_dir/$tfile
18738
18739         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18740         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18741         local old_dir_mode=$(stat -c%f $migrate_dir)
18742         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18743
18744         mkdir -p $migrate_dir/dir_default_stripe2
18745         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18746         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18747
18748         mkdir -p $other_dir
18749         ln $migrate_dir/$tfile $other_dir/luna
18750         ln $migrate_dir/$tfile $migrate_dir/sofia
18751         ln $other_dir/$tfile $migrate_dir/david
18752         ln -s $migrate_dir/$tfile $other_dir/zachary
18753         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18754         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18755
18756         local len
18757         local lnktgt
18758
18759         # inline symlink
18760         for len in 58 59 60; do
18761                 lnktgt=$(str_repeat 'l' $len)
18762                 touch $migrate_dir/$lnktgt
18763                 ln -s $lnktgt $migrate_dir/${len}char_ln
18764         done
18765
18766         # PATH_MAX
18767         for len in 4094 4095; do
18768                 lnktgt=$(str_repeat 'l' $len)
18769                 ln -s $lnktgt $migrate_dir/${len}char_ln
18770         done
18771
18772         # NAME_MAX
18773         for len in 254 255; do
18774                 touch $migrate_dir/$(str_repeat 'l' $len)
18775         done
18776
18777         $LFS migrate -m $MDTIDX $migrate_dir ||
18778                 error "fails on migrating remote dir to MDT1"
18779
18780         echo "migratate to MDT1, then checking.."
18781         for ((i = 0; i < 10; i++)); do
18782                 for file in $(find $migrate_dir/dir_${i}); do
18783                         mdt_index=$($LFS getstripe -m $file)
18784                         # broken symlink getstripe will fail
18785                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18786                                 error "$file is not on MDT${MDTIDX}"
18787                 done
18788         done
18789
18790         # the multiple link file should still in MDT0
18791         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18792         [ $mdt_index == 0 ] ||
18793                 error "$file is not on MDT${MDTIDX}"
18794
18795         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18796         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18797                 error " expect $old_dir_flag get $new_dir_flag"
18798
18799         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18800         [ "$old_file_flag" = "$new_file_flag" ] ||
18801                 error " expect $old_file_flag get $new_file_flag"
18802
18803         local new_dir_mode=$(stat -c%f $migrate_dir)
18804         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18805                 error "expect mode $old_dir_mode get $new_dir_mode"
18806
18807         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18808         [ "$old_file_mode" = "$new_file_mode" ] ||
18809                 error "expect mode $old_file_mode get $new_file_mode"
18810
18811         diff /etc/passwd $migrate_dir/$tfile ||
18812                 error "$tfile different after migration"
18813
18814         diff /etc/passwd $other_dir/luna ||
18815                 error "luna different after migration"
18816
18817         diff /etc/passwd $migrate_dir/sofia ||
18818                 error "sofia different after migration"
18819
18820         diff /etc/passwd $migrate_dir/david ||
18821                 error "david different after migration"
18822
18823         diff /etc/passwd $other_dir/zachary ||
18824                 error "zachary different after migration"
18825
18826         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18827                 error "${tfile}_ln different after migration"
18828
18829         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18830                 error "${tfile}_ln_other different after migration"
18831
18832         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18833         [ $stripe_count = 2 ] ||
18834                 error "dir strpe_count $d != 2 after migration."
18835
18836         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18837         [ $stripe_count = 2 ] ||
18838                 error "file strpe_count $d != 2 after migration."
18839
18840         #migrate back to MDT0
18841         MDTIDX=0
18842
18843         $LFS migrate -m $MDTIDX $migrate_dir ||
18844                 error "fails on migrating remote dir to MDT0"
18845
18846         echo "migrate back to MDT0, checking.."
18847         for file in $(find $migrate_dir); do
18848                 mdt_index=$($LFS getstripe -m $file)
18849                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18850                         error "$file is not on MDT${MDTIDX}"
18851         done
18852
18853         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18854         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18855                 error " expect $old_dir_flag get $new_dir_flag"
18856
18857         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18858         [ "$old_file_flag" = "$new_file_flag" ] ||
18859                 error " expect $old_file_flag get $new_file_flag"
18860
18861         local new_dir_mode=$(stat -c%f $migrate_dir)
18862         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18863                 error "expect mode $old_dir_mode get $new_dir_mode"
18864
18865         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18866         [ "$old_file_mode" = "$new_file_mode" ] ||
18867                 error "expect mode $old_file_mode get $new_file_mode"
18868
18869         diff /etc/passwd ${migrate_dir}/$tfile ||
18870                 error "$tfile different after migration"
18871
18872         diff /etc/passwd ${other_dir}/luna ||
18873                 error "luna different after migration"
18874
18875         diff /etc/passwd ${migrate_dir}/sofia ||
18876                 error "sofia different after migration"
18877
18878         diff /etc/passwd ${other_dir}/zachary ||
18879                 error "zachary different after migration"
18880
18881         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18882                 error "${tfile}_ln different after migration"
18883
18884         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18885                 error "${tfile}_ln_other different after migration"
18886
18887         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18888         [ $stripe_count = 2 ] ||
18889                 error "dir strpe_count $d != 2 after migration."
18890
18891         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18892         [ $stripe_count = 2 ] ||
18893                 error "file strpe_count $d != 2 after migration."
18894
18895         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18896 }
18897 run_test 230b "migrate directory"
18898
18899 test_230c() {
18900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18902         remote_mds_nodsh && skip "remote MDS with nodsh"
18903         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18904                 skip "Need MDS version at least 2.11.52"
18905
18906         local MDTIDX=1
18907         local total=3
18908         local mdt_index
18909         local file
18910         local migrate_dir=$DIR/$tdir/migrate_dir
18911
18912         #If migrating directory fails in the middle, all entries of
18913         #the directory is still accessiable.
18914         test_mkdir $DIR/$tdir
18915         test_mkdir -i0 -c1 $migrate_dir
18916         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18917         stat $migrate_dir
18918         createmany -o $migrate_dir/f $total ||
18919                 error "create files under ${migrate_dir} failed"
18920
18921         # fail after migrating top dir, and this will fail only once, so the
18922         # first sub file migration will fail (currently f3), others succeed.
18923         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18924         do_facet mds1 lctl set_param fail_loc=0x1801
18925         local t=$(ls $migrate_dir | wc -l)
18926         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18927                 error "migrate should fail"
18928         local u=$(ls $migrate_dir | wc -l)
18929         [ "$u" == "$t" ] || error "$u != $t during migration"
18930
18931         # add new dir/file should succeed
18932         mkdir $migrate_dir/dir ||
18933                 error "mkdir failed under migrating directory"
18934         touch $migrate_dir/file ||
18935                 error "create file failed under migrating directory"
18936
18937         # add file with existing name should fail
18938         for file in $migrate_dir/f*; do
18939                 stat $file > /dev/null || error "stat $file failed"
18940                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18941                         error "open(O_CREAT|O_EXCL) $file should fail"
18942                 $MULTIOP $file m && error "create $file should fail"
18943                 touch $DIR/$tdir/remote_dir/$tfile ||
18944                         error "touch $tfile failed"
18945                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18946                         error "link $file should fail"
18947                 mdt_index=$($LFS getstripe -m $file)
18948                 if [ $mdt_index == 0 ]; then
18949                         # file failed to migrate is not allowed to rename to
18950                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18951                                 error "rename to $file should fail"
18952                 else
18953                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18954                                 error "rename to $file failed"
18955                 fi
18956                 echo hello >> $file || error "write $file failed"
18957         done
18958
18959         # resume migration with different options should fail
18960         $LFS migrate -m 0 $migrate_dir &&
18961                 error "migrate -m 0 $migrate_dir should fail"
18962
18963         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18964                 error "migrate -c 2 $migrate_dir should fail"
18965
18966         # resume migration should succeed
18967         $LFS migrate -m $MDTIDX $migrate_dir ||
18968                 error "migrate $migrate_dir failed"
18969
18970         echo "Finish migration, then checking.."
18971         for file in $(find $migrate_dir); do
18972                 mdt_index=$($LFS getstripe -m $file)
18973                 [ $mdt_index == $MDTIDX ] ||
18974                         error "$file is not on MDT${MDTIDX}"
18975         done
18976
18977         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18978 }
18979 run_test 230c "check directory accessiblity if migration failed"
18980
18981 test_230d() {
18982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18984         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18985                 skip "Need MDS version at least 2.11.52"
18986         # LU-11235
18987         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18988
18989         local migrate_dir=$DIR/$tdir/migrate_dir
18990         local old_index
18991         local new_index
18992         local old_count
18993         local new_count
18994         local new_hash
18995         local mdt_index
18996         local i
18997         local j
18998
18999         old_index=$((RANDOM % MDSCOUNT))
19000         old_count=$((MDSCOUNT - old_index))
19001         new_index=$((RANDOM % MDSCOUNT))
19002         new_count=$((MDSCOUNT - new_index))
19003         new_hash=1 # for all_char
19004
19005         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19006         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19007
19008         test_mkdir $DIR/$tdir
19009         test_mkdir -i $old_index -c $old_count $migrate_dir
19010
19011         for ((i=0; i<100; i++)); do
19012                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19013                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19014                         error "create files under remote dir failed $i"
19015         done
19016
19017         echo -n "Migrate from MDT$old_index "
19018         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19019         echo -n "to MDT$new_index"
19020         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19021         echo
19022
19023         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19024         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19025                 error "migrate remote dir error"
19026
19027         echo "Finish migration, then checking.."
19028         for file in $(find $migrate_dir); do
19029                 mdt_index=$($LFS getstripe -m $file)
19030                 if [ $mdt_index -lt $new_index ] ||
19031                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19032                         error "$file is on MDT$mdt_index"
19033                 fi
19034         done
19035
19036         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19037 }
19038 run_test 230d "check migrate big directory"
19039
19040 test_230e() {
19041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19043         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19044                 skip "Need MDS version at least 2.11.52"
19045
19046         local i
19047         local j
19048         local a_fid
19049         local b_fid
19050
19051         mkdir -p $DIR/$tdir
19052         mkdir $DIR/$tdir/migrate_dir
19053         mkdir $DIR/$tdir/other_dir
19054         touch $DIR/$tdir/migrate_dir/a
19055         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19056         ls $DIR/$tdir/other_dir
19057
19058         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19059                 error "migrate dir fails"
19060
19061         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19062         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19063
19064         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19065         [ $mdt_index == 0 ] || error "a is not on MDT0"
19066
19067         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19068                 error "migrate dir fails"
19069
19070         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19071         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19072
19073         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19074         [ $mdt_index == 1 ] || error "a is not on MDT1"
19075
19076         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19077         [ $mdt_index == 1 ] || error "b is not on MDT1"
19078
19079         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19080         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19081
19082         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19083
19084         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19085 }
19086 run_test 230e "migrate mulitple local link files"
19087
19088 test_230f() {
19089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19091         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19092                 skip "Need MDS version at least 2.11.52"
19093
19094         local a_fid
19095         local ln_fid
19096
19097         mkdir -p $DIR/$tdir
19098         mkdir $DIR/$tdir/migrate_dir
19099         $LFS mkdir -i1 $DIR/$tdir/other_dir
19100         touch $DIR/$tdir/migrate_dir/a
19101         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19102         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19103         ls $DIR/$tdir/other_dir
19104
19105         # a should be migrated to MDT1, since no other links on MDT0
19106         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19107                 error "#1 migrate dir fails"
19108         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19109         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19110         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19111         [ $mdt_index == 1 ] || error "a is not on MDT1"
19112
19113         # a should stay on MDT1, because it is a mulitple link file
19114         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19115                 error "#2 migrate dir fails"
19116         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19117         [ $mdt_index == 1 ] || error "a is not on MDT1"
19118
19119         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19120                 error "#3 migrate dir fails"
19121
19122         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19123         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19124         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19125
19126         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19127         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19128
19129         # a should be migrated to MDT0, since no other links on MDT1
19130         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19131                 error "#4 migrate dir fails"
19132         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19133         [ $mdt_index == 0 ] || error "a is not on MDT0"
19134
19135         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19136 }
19137 run_test 230f "migrate mulitple remote link files"
19138
19139 test_230g() {
19140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19142         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19143                 skip "Need MDS version at least 2.11.52"
19144
19145         mkdir -p $DIR/$tdir/migrate_dir
19146
19147         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19148                 error "migrating dir to non-exist MDT succeeds"
19149         true
19150 }
19151 run_test 230g "migrate dir to non-exist MDT"
19152
19153 test_230h() {
19154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19156         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19157                 skip "Need MDS version at least 2.11.52"
19158
19159         local mdt_index
19160
19161         mkdir -p $DIR/$tdir/migrate_dir
19162
19163         $LFS migrate -m1 $DIR &&
19164                 error "migrating mountpoint1 should fail"
19165
19166         $LFS migrate -m1 $DIR/$tdir/.. &&
19167                 error "migrating mountpoint2 should fail"
19168
19169         # same as mv
19170         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19171                 error "migrating $tdir/migrate_dir/.. should fail"
19172
19173         true
19174 }
19175 run_test 230h "migrate .. and root"
19176
19177 test_230i() {
19178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19180         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19181                 skip "Need MDS version at least 2.11.52"
19182
19183         mkdir -p $DIR/$tdir/migrate_dir
19184
19185         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19186                 error "migration fails with a tailing slash"
19187
19188         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19189                 error "migration fails with two tailing slashes"
19190 }
19191 run_test 230i "lfs migrate -m tolerates trailing slashes"
19192
19193 test_230j() {
19194         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19195         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19196                 skip "Need MDS version at least 2.11.52"
19197
19198         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19199         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19200                 error "create $tfile failed"
19201         cat /etc/passwd > $DIR/$tdir/$tfile
19202
19203         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19204
19205         cmp /etc/passwd $DIR/$tdir/$tfile ||
19206                 error "DoM file mismatch after migration"
19207 }
19208 run_test 230j "DoM file data not changed after dir migration"
19209
19210 test_230k() {
19211         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19212         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19213                 skip "Need MDS version at least 2.11.56"
19214
19215         local total=20
19216         local files_on_starting_mdt=0
19217
19218         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19219         $LFS getdirstripe $DIR/$tdir
19220         for i in $(seq $total); do
19221                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19222                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19223                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19224         done
19225
19226         echo "$files_on_starting_mdt files on MDT0"
19227
19228         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19229         $LFS getdirstripe $DIR/$tdir
19230
19231         files_on_starting_mdt=0
19232         for i in $(seq $total); do
19233                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19234                         error "file $tfile.$i mismatch after migration"
19235                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19236                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19237         done
19238
19239         echo "$files_on_starting_mdt files on MDT1 after migration"
19240         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19241
19242         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19243         $LFS getdirstripe $DIR/$tdir
19244
19245         files_on_starting_mdt=0
19246         for i in $(seq $total); do
19247                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19248                         error "file $tfile.$i mismatch after 2nd migration"
19249                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19250                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19251         done
19252
19253         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19254         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19255
19256         true
19257 }
19258 run_test 230k "file data not changed after dir migration"
19259
19260 test_230l() {
19261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19262         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19263                 skip "Need MDS version at least 2.11.56"
19264
19265         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19266         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19267                 error "create files under remote dir failed $i"
19268         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19269 }
19270 run_test 230l "readdir between MDTs won't crash"
19271
19272 test_230m() {
19273         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19274         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19275                 skip "Need MDS version at least 2.11.56"
19276
19277         local MDTIDX=1
19278         local mig_dir=$DIR/$tdir/migrate_dir
19279         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19280         local shortstr="b"
19281         local val
19282
19283         echo "Creating files and dirs with xattrs"
19284         test_mkdir $DIR/$tdir
19285         test_mkdir -i0 -c1 $mig_dir
19286         mkdir $mig_dir/dir
19287         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19288                 error "cannot set xattr attr1 on dir"
19289         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19290                 error "cannot set xattr attr2 on dir"
19291         touch $mig_dir/dir/f0
19292         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19293                 error "cannot set xattr attr1 on file"
19294         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19295                 error "cannot set xattr attr2 on file"
19296         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19297         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19298         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19299         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19300         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19301         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19302         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19303         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19304         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19305
19306         echo "Migrating to MDT1"
19307         $LFS migrate -m $MDTIDX $mig_dir ||
19308                 error "fails on migrating dir to MDT1"
19309
19310         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19311         echo "Checking xattrs"
19312         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19313         [ "$val" = $longstr ] ||
19314                 error "expecting xattr1 $longstr on dir, found $val"
19315         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19316         [ "$val" = $shortstr ] ||
19317                 error "expecting xattr2 $shortstr on dir, found $val"
19318         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19319         [ "$val" = $longstr ] ||
19320                 error "expecting xattr1 $longstr on file, found $val"
19321         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19322         [ "$val" = $shortstr ] ||
19323                 error "expecting xattr2 $shortstr on file, found $val"
19324 }
19325 run_test 230m "xattrs not changed after dir migration"
19326
19327 test_230n() {
19328         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19329         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19330                 skip "Need MDS version at least 2.13.53"
19331
19332         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19333         cat /etc/hosts > $DIR/$tdir/$tfile
19334         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19335         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19336
19337         cmp /etc/hosts $DIR/$tdir/$tfile ||
19338                 error "File data mismatch after migration"
19339 }
19340 run_test 230n "Dir migration with mirrored file"
19341
19342 test_230o() {
19343         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19344         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19345                 skip "Need MDS version at least 2.13.52"
19346
19347         local mdts=$(comma_list $(mdts_nodes))
19348         local timeout=100
19349         local restripe_status
19350         local delta
19351         local i
19352
19353         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19354
19355         # in case "crush" hash type is not set
19356         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19357
19358         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19359                            mdt.*MDT0000.enable_dir_restripe)
19360         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19361         stack_trap "do_nodes $mdts $LCTL set_param \
19362                     mdt.*.enable_dir_restripe=$restripe_status"
19363
19364         mkdir $DIR/$tdir
19365         createmany -m $DIR/$tdir/f 100 ||
19366                 error "create files under remote dir failed $i"
19367         createmany -d $DIR/$tdir/d 100 ||
19368                 error "create dirs under remote dir failed $i"
19369
19370         for i in $(seq 2 $MDSCOUNT); do
19371                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19372                 $LFS setdirstripe -c $i $DIR/$tdir ||
19373                         error "split -c $i $tdir failed"
19374                 wait_update $HOSTNAME \
19375                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19376                         error "dir split not finished"
19377                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19378                         awk '/migrate/ {sum += $2} END { print sum }')
19379                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19380                 # delta is around total_files/stripe_count
19381                 (( $delta < 200 / (i - 1) + 4 )) ||
19382                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19383         done
19384 }
19385 run_test 230o "dir split"
19386
19387 test_230p() {
19388         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19389         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19390                 skip "Need MDS version at least 2.13.52"
19391
19392         local mdts=$(comma_list $(mdts_nodes))
19393         local timeout=100
19394         local restripe_status
19395         local delta
19396         local i
19397
19398         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19399
19400         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19401
19402         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19403                            mdt.*MDT0000.enable_dir_restripe)
19404         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19405         stack_trap "do_nodes $mdts $LCTL set_param \
19406                     mdt.*.enable_dir_restripe=$restripe_status"
19407
19408         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19409         createmany -m $DIR/$tdir/f 100 ||
19410                 error "create files under remote dir failed $i"
19411         createmany -d $DIR/$tdir/d 100 ||
19412                 error "create dirs under remote dir failed $i"
19413
19414         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19415                 local mdt_hash="crush"
19416
19417                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19418                 $LFS setdirstripe -c $i $DIR/$tdir ||
19419                         error "split -c $i $tdir failed"
19420                 [ $i -eq 1 ] && mdt_hash="none"
19421                 wait_update $HOSTNAME \
19422                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19423                         error "dir merge not finished"
19424                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19425                         awk '/migrate/ {sum += $2} END { print sum }')
19426                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19427                 # delta is around total_files/stripe_count
19428                 (( $delta < 200 / i + 4 )) ||
19429                         error "$delta files migrated >= $((200 / i + 4))"
19430         done
19431 }
19432 run_test 230p "dir merge"
19433
19434 test_230q() {
19435         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19436         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19437                 skip "Need MDS version at least 2.13.52"
19438
19439         local mdts=$(comma_list $(mdts_nodes))
19440         local saved_threshold=$(do_facet mds1 \
19441                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19442         local saved_delta=$(do_facet mds1 \
19443                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19444         local threshold=100
19445         local delta=2
19446         local total=0
19447         local stripe_count=0
19448         local stripe_index
19449         local nr_files
19450         local create
19451
19452         # test with fewer files on ZFS
19453         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19454
19455         stack_trap "do_nodes $mdts $LCTL set_param \
19456                     mdt.*.dir_split_count=$saved_threshold"
19457         stack_trap "do_nodes $mdts $LCTL set_param \
19458                     mdt.*.dir_split_delta=$saved_delta"
19459         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19460         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19461         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19462         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19463         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19464         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19465
19466         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19467         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19468
19469         create=$((threshold * 3 / 2))
19470         while [ $stripe_count -lt $MDSCOUNT ]; do
19471                 createmany -m $DIR/$tdir/f $total $create ||
19472                         error "create sub files failed"
19473                 stat $DIR/$tdir > /dev/null
19474                 total=$((total + create))
19475                 stripe_count=$((stripe_count + delta))
19476                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19477
19478                 wait_update $HOSTNAME \
19479                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19480                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19481
19482                 wait_update $HOSTNAME \
19483                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19484                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19485
19486                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19487                 echo "$nr_files/$total files on MDT$stripe_index after split"
19488                 # allow 10% margin of imbalance with crush hash
19489                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19490                         error "$nr_files files on MDT$stripe_index after split"
19491
19492                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19493                 [ $nr_files -eq $total ] ||
19494                         error "total sub files $nr_files != $total"
19495         done
19496 }
19497 run_test 230q "dir auto split"
19498
19499 test_230r() {
19500         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19501         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19502         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19503                 skip "Need MDS version at least 2.13.54"
19504
19505         # maximum amount of local locks:
19506         # parent striped dir - 2 locks
19507         # new stripe in parent to migrate to - 1 lock
19508         # source and target - 2 locks
19509         # Total 5 locks for regular file
19510         mkdir -p $DIR/$tdir
19511         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19512         touch $DIR/$tdir/dir1/eee
19513
19514         # create 4 hardlink for 4 more locks
19515         # Total: 9 locks > RS_MAX_LOCKS (8)
19516         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19517         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19518         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19519         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19520         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19521         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19522         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19523         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19524
19525         cancel_lru_locks mdc
19526
19527         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19528                 error "migrate dir fails"
19529
19530         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19531 }
19532 run_test 230r "migrate with too many local locks"
19533
19534 test_230s() {
19535         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19536                 skip "Need MDS version at least 2.13.57"
19537
19538         local mdts=$(comma_list $(mdts_nodes))
19539         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19540                                 mdt.*MDT0000.enable_dir_restripe)
19541
19542         stack_trap "do_nodes $mdts $LCTL set_param \
19543                     mdt.*.enable_dir_restripe=$restripe_status"
19544
19545         local st
19546         for st in 0 1; do
19547                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19548                 test_mkdir $DIR/$tdir
19549                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19550                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19551                 rmdir $DIR/$tdir
19552         done
19553 }
19554 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19555
19556 test_230t()
19557 {
19558         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19559         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19560                 skip "Need MDS version at least 2.14.50"
19561
19562         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19563         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19564         $LFS project -p 1 -s $DIR/$tdir ||
19565                 error "set $tdir project id failed"
19566         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19567                 error "set subdir project id failed"
19568         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19569 }
19570 run_test 230t "migrate directory with project ID set"
19571
19572 test_231a()
19573 {
19574         # For simplicity this test assumes that max_pages_per_rpc
19575         # is the same across all OSCs
19576         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19577         local bulk_size=$((max_pages * PAGE_SIZE))
19578         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19579                                        head -n 1)
19580
19581         mkdir -p $DIR/$tdir
19582         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19583                 error "failed to set stripe with -S ${brw_size}M option"
19584
19585         # clear the OSC stats
19586         $LCTL set_param osc.*.stats=0 &>/dev/null
19587         stop_writeback
19588
19589         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19590         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19591                 oflag=direct &>/dev/null || error "dd failed"
19592
19593         sync; sleep 1; sync # just to be safe
19594         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19595         if [ x$nrpcs != "x1" ]; then
19596                 $LCTL get_param osc.*.stats
19597                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19598         fi
19599
19600         start_writeback
19601         # Drop the OSC cache, otherwise we will read from it
19602         cancel_lru_locks osc
19603
19604         # clear the OSC stats
19605         $LCTL set_param osc.*.stats=0 &>/dev/null
19606
19607         # Client reads $bulk_size.
19608         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19609                 iflag=direct &>/dev/null || error "dd failed"
19610
19611         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19612         if [ x$nrpcs != "x1" ]; then
19613                 $LCTL get_param osc.*.stats
19614                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19615         fi
19616 }
19617 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19618
19619 test_231b() {
19620         mkdir -p $DIR/$tdir
19621         local i
19622         for i in {0..1023}; do
19623                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19624                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19625                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19626         done
19627         sync
19628 }
19629 run_test 231b "must not assert on fully utilized OST request buffer"
19630
19631 test_232a() {
19632         mkdir -p $DIR/$tdir
19633         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19634
19635         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19636         do_facet ost1 $LCTL set_param fail_loc=0x31c
19637
19638         # ignore dd failure
19639         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19640
19641         do_facet ost1 $LCTL set_param fail_loc=0
19642         umount_client $MOUNT || error "umount failed"
19643         mount_client $MOUNT || error "mount failed"
19644         stop ost1 || error "cannot stop ost1"
19645         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19646 }
19647 run_test 232a "failed lock should not block umount"
19648
19649 test_232b() {
19650         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19651                 skip "Need MDS version at least 2.10.58"
19652
19653         mkdir -p $DIR/$tdir
19654         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19656         sync
19657         cancel_lru_locks osc
19658
19659         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19660         do_facet ost1 $LCTL set_param fail_loc=0x31c
19661
19662         # ignore failure
19663         $LFS data_version $DIR/$tdir/$tfile || true
19664
19665         do_facet ost1 $LCTL set_param fail_loc=0
19666         umount_client $MOUNT || error "umount failed"
19667         mount_client $MOUNT || error "mount failed"
19668         stop ost1 || error "cannot stop ost1"
19669         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19670 }
19671 run_test 232b "failed data version lock should not block umount"
19672
19673 test_233a() {
19674         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19675                 skip "Need MDS version at least 2.3.64"
19676         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19677
19678         local fid=$($LFS path2fid $MOUNT)
19679
19680         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19681                 error "cannot access $MOUNT using its FID '$fid'"
19682 }
19683 run_test 233a "checking that OBF of the FS root succeeds"
19684
19685 test_233b() {
19686         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19687                 skip "Need MDS version at least 2.5.90"
19688         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19689
19690         local fid=$($LFS path2fid $MOUNT/.lustre)
19691
19692         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19693                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19694
19695         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19696         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19697                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19698 }
19699 run_test 233b "checking that OBF of the FS .lustre succeeds"
19700
19701 test_234() {
19702         local p="$TMP/sanityN-$TESTNAME.parameters"
19703         save_lustre_params client "llite.*.xattr_cache" > $p
19704         lctl set_param llite.*.xattr_cache 1 ||
19705                 skip_env "xattr cache is not supported"
19706
19707         mkdir -p $DIR/$tdir || error "mkdir failed"
19708         touch $DIR/$tdir/$tfile || error "touch failed"
19709         # OBD_FAIL_LLITE_XATTR_ENOMEM
19710         $LCTL set_param fail_loc=0x1405
19711         getfattr -n user.attr $DIR/$tdir/$tfile &&
19712                 error "getfattr should have failed with ENOMEM"
19713         $LCTL set_param fail_loc=0x0
19714         rm -rf $DIR/$tdir
19715
19716         restore_lustre_params < $p
19717         rm -f $p
19718 }
19719 run_test 234 "xattr cache should not crash on ENOMEM"
19720
19721 test_235() {
19722         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19723                 skip "Need MDS version at least 2.4.52"
19724
19725         flock_deadlock $DIR/$tfile
19726         local RC=$?
19727         case $RC in
19728                 0)
19729                 ;;
19730                 124) error "process hangs on a deadlock"
19731                 ;;
19732                 *) error "error executing flock_deadlock $DIR/$tfile"
19733                 ;;
19734         esac
19735 }
19736 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19737
19738 #LU-2935
19739 test_236() {
19740         check_swap_layouts_support
19741
19742         local ref1=/etc/passwd
19743         local ref2=/etc/group
19744         local file1=$DIR/$tdir/f1
19745         local file2=$DIR/$tdir/f2
19746
19747         test_mkdir -c1 $DIR/$tdir
19748         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19749         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19750         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19751         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19752         local fd=$(free_fd)
19753         local cmd="exec $fd<>$file2"
19754         eval $cmd
19755         rm $file2
19756         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19757                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19758         cmd="exec $fd>&-"
19759         eval $cmd
19760         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19761
19762         #cleanup
19763         rm -rf $DIR/$tdir
19764 }
19765 run_test 236 "Layout swap on open unlinked file"
19766
19767 # LU-4659 linkea consistency
19768 test_238() {
19769         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19770                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19771                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19772                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19773
19774         touch $DIR/$tfile
19775         ln $DIR/$tfile $DIR/$tfile.lnk
19776         touch $DIR/$tfile.new
19777         mv $DIR/$tfile.new $DIR/$tfile
19778         local fid1=$($LFS path2fid $DIR/$tfile)
19779         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19780         local path1=$($LFS fid2path $FSNAME "$fid1")
19781         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19782         local path2=$($LFS fid2path $FSNAME "$fid2")
19783         [ $tfile.lnk == $path2 ] ||
19784                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19785         rm -f $DIR/$tfile*
19786 }
19787 run_test 238 "Verify linkea consistency"
19788
19789 test_239A() { # was test_239
19790         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19791                 skip "Need MDS version at least 2.5.60"
19792
19793         local list=$(comma_list $(mdts_nodes))
19794
19795         mkdir -p $DIR/$tdir
19796         createmany -o $DIR/$tdir/f- 5000
19797         unlinkmany $DIR/$tdir/f- 5000
19798         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19799                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19800         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19801                         osp.*MDT*.sync_in_flight" | calc_sum)
19802         [ "$changes" -eq 0 ] || error "$changes not synced"
19803 }
19804 run_test 239A "osp_sync test"
19805
19806 test_239a() { #LU-5297
19807         remote_mds_nodsh && skip "remote MDS with nodsh"
19808
19809         touch $DIR/$tfile
19810         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19811         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19812         chgrp $RUNAS_GID $DIR/$tfile
19813         wait_delete_completed
19814 }
19815 run_test 239a "process invalid osp sync record correctly"
19816
19817 test_239b() { #LU-5297
19818         remote_mds_nodsh && skip "remote MDS with nodsh"
19819
19820         touch $DIR/$tfile1
19821         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19822         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19823         chgrp $RUNAS_GID $DIR/$tfile1
19824         wait_delete_completed
19825         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19826         touch $DIR/$tfile2
19827         chgrp $RUNAS_GID $DIR/$tfile2
19828         wait_delete_completed
19829 }
19830 run_test 239b "process osp sync record with ENOMEM error correctly"
19831
19832 test_240() {
19833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19834         remote_mds_nodsh && skip "remote MDS with nodsh"
19835
19836         mkdir -p $DIR/$tdir
19837
19838         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19839                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19840         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19841                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19842
19843         umount_client $MOUNT || error "umount failed"
19844         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19845         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19846         mount_client $MOUNT || error "failed to mount client"
19847
19848         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19849         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19850 }
19851 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19852
19853 test_241_bio() {
19854         local count=$1
19855         local bsize=$2
19856
19857         for LOOP in $(seq $count); do
19858                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19859                 cancel_lru_locks $OSC || true
19860         done
19861 }
19862
19863 test_241_dio() {
19864         local count=$1
19865         local bsize=$2
19866
19867         for LOOP in $(seq $1); do
19868                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19869                         2>/dev/null
19870         done
19871 }
19872
19873 test_241a() { # was test_241
19874         local bsize=$PAGE_SIZE
19875
19876         (( bsize < 40960 )) && bsize=40960
19877         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19878         ls -la $DIR/$tfile
19879         cancel_lru_locks $OSC
19880         test_241_bio 1000 $bsize &
19881         PID=$!
19882         test_241_dio 1000 $bsize
19883         wait $PID
19884 }
19885 run_test 241a "bio vs dio"
19886
19887 test_241b() {
19888         local bsize=$PAGE_SIZE
19889
19890         (( bsize < 40960 )) && bsize=40960
19891         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19892         ls -la $DIR/$tfile
19893         test_241_dio 1000 $bsize &
19894         PID=$!
19895         test_241_dio 1000 $bsize
19896         wait $PID
19897 }
19898 run_test 241b "dio vs dio"
19899
19900 test_242() {
19901         remote_mds_nodsh && skip "remote MDS with nodsh"
19902
19903         mkdir -p $DIR/$tdir
19904         touch $DIR/$tdir/$tfile
19905
19906         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19907         do_facet mds1 lctl set_param fail_loc=0x105
19908         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19909
19910         do_facet mds1 lctl set_param fail_loc=0
19911         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19912 }
19913 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19914
19915 test_243()
19916 {
19917         test_mkdir $DIR/$tdir
19918         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19919 }
19920 run_test 243 "various group lock tests"
19921
19922 test_244a()
19923 {
19924         test_mkdir $DIR/$tdir
19925         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19926         sendfile_grouplock $DIR/$tdir/$tfile || \
19927                 error "sendfile+grouplock failed"
19928         rm -rf $DIR/$tdir
19929 }
19930 run_test 244a "sendfile with group lock tests"
19931
19932 test_244b()
19933 {
19934         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19935
19936         local threads=50
19937         local size=$((1024*1024))
19938
19939         test_mkdir $DIR/$tdir
19940         for i in $(seq 1 $threads); do
19941                 local file=$DIR/$tdir/file_$((i / 10))
19942                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19943                 local pids[$i]=$!
19944         done
19945         for i in $(seq 1 $threads); do
19946                 wait ${pids[$i]}
19947         done
19948 }
19949 run_test 244b "multi-threaded write with group lock"
19950
19951 test_245() {
19952         local flagname="multi_mod_rpcs"
19953         local connect_data_name="max_mod_rpcs"
19954         local out
19955
19956         # check if multiple modify RPCs flag is set
19957         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19958                 grep "connect_flags:")
19959         echo "$out"
19960
19961         echo "$out" | grep -qw $flagname
19962         if [ $? -ne 0 ]; then
19963                 echo "connect flag $flagname is not set"
19964                 return
19965         fi
19966
19967         # check if multiple modify RPCs data is set
19968         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19969         echo "$out"
19970
19971         echo "$out" | grep -qw $connect_data_name ||
19972                 error "import should have connect data $connect_data_name"
19973 }
19974 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19975
19976 cleanup_247() {
19977         local submount=$1
19978
19979         trap 0
19980         umount_client $submount
19981         rmdir $submount
19982 }
19983
19984 test_247a() {
19985         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19986                 grep -q subtree ||
19987                 skip_env "Fileset feature is not supported"
19988
19989         local submount=${MOUNT}_$tdir
19990
19991         mkdir $MOUNT/$tdir
19992         mkdir -p $submount || error "mkdir $submount failed"
19993         FILESET="$FILESET/$tdir" mount_client $submount ||
19994                 error "mount $submount failed"
19995         trap "cleanup_247 $submount" EXIT
19996         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19997         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19998                 error "read $MOUNT/$tdir/$tfile failed"
19999         cleanup_247 $submount
20000 }
20001 run_test 247a "mount subdir as fileset"
20002
20003 test_247b() {
20004         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20005                 skip_env "Fileset feature is not supported"
20006
20007         local submount=${MOUNT}_$tdir
20008
20009         rm -rf $MOUNT/$tdir
20010         mkdir -p $submount || error "mkdir $submount failed"
20011         SKIP_FILESET=1
20012         FILESET="$FILESET/$tdir" mount_client $submount &&
20013                 error "mount $submount should fail"
20014         rmdir $submount
20015 }
20016 run_test 247b "mount subdir that dose not exist"
20017
20018 test_247c() {
20019         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20020                 skip_env "Fileset feature is not supported"
20021
20022         local submount=${MOUNT}_$tdir
20023
20024         mkdir -p $MOUNT/$tdir/dir1
20025         mkdir -p $submount || error "mkdir $submount failed"
20026         trap "cleanup_247 $submount" EXIT
20027         FILESET="$FILESET/$tdir" mount_client $submount ||
20028                 error "mount $submount failed"
20029         local fid=$($LFS path2fid $MOUNT/)
20030         $LFS fid2path $submount $fid && error "fid2path should fail"
20031         cleanup_247 $submount
20032 }
20033 run_test 247c "running fid2path outside subdirectory root"
20034
20035 test_247d() {
20036         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20037                 skip "Fileset feature is not supported"
20038
20039         local submount=${MOUNT}_$tdir
20040
20041         mkdir -p $MOUNT/$tdir/dir1
20042         mkdir -p $submount || error "mkdir $submount failed"
20043         FILESET="$FILESET/$tdir" mount_client $submount ||
20044                 error "mount $submount failed"
20045         trap "cleanup_247 $submount" EXIT
20046
20047         local td=$submount/dir1
20048         local fid=$($LFS path2fid $td)
20049         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20050
20051         # check that we get the same pathname back
20052         local rootpath
20053         local found
20054         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20055                 echo "$rootpath $fid"
20056                 found=$($LFS fid2path $rootpath "$fid")
20057                 [ -n "found" ] || error "fid2path should succeed"
20058                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20059         done
20060         # check wrong root path format
20061         rootpath=$submount"_wrong"
20062         found=$($LFS fid2path $rootpath "$fid")
20063         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20064
20065         cleanup_247 $submount
20066 }
20067 run_test 247d "running fid2path inside subdirectory root"
20068
20069 # LU-8037
20070 test_247e() {
20071         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20072                 grep -q subtree ||
20073                 skip "Fileset feature is not supported"
20074
20075         local submount=${MOUNT}_$tdir
20076
20077         mkdir $MOUNT/$tdir
20078         mkdir -p $submount || error "mkdir $submount failed"
20079         FILESET="$FILESET/.." mount_client $submount &&
20080                 error "mount $submount should fail"
20081         rmdir $submount
20082 }
20083 run_test 247e "mount .. as fileset"
20084
20085 test_247f() {
20086         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20087         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20088                 skip "Need at least version 2.13.52"
20089         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20090                 skip "Need at least version 2.14.50"
20091         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20092                 grep -q subtree ||
20093                 skip "Fileset feature is not supported"
20094
20095         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20096         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20097                 error "mkdir remote failed"
20098         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20099         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20100                 error "mkdir striped failed"
20101         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20102
20103         local submount=${MOUNT}_$tdir
20104
20105         mkdir -p $submount || error "mkdir $submount failed"
20106         stack_trap "rmdir $submount"
20107
20108         local dir
20109         local stat
20110         local fileset=$FILESET
20111         local mdts=$(comma_list $(mdts_nodes))
20112
20113         stat=$(do_facet mds1 $LCTL get_param -n \
20114                 mdt.*MDT0000.enable_remote_subdir_mount)
20115         stack_trap "do_nodes $mdts $LCTL set_param \
20116                 mdt.*.enable_remote_subdir_mount=$stat"
20117
20118         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20119         stack_trap "umount_client $submount"
20120         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20121                 error "mount remote dir $dir should fail"
20122
20123         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20124                 $tdir/striped/. ; do
20125                 FILESET="$fileset/$dir" mount_client $submount ||
20126                         error "mount $dir failed"
20127                 umount_client $submount
20128         done
20129
20130         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20131         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20132                 error "mount $tdir/remote failed"
20133 }
20134 run_test 247f "mount striped or remote directory as fileset"
20135
20136 test_247g() {
20137         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20138         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20139                 skip "Need at least version 2.14.50"
20140
20141         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20142                 error "mkdir $tdir failed"
20143         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20144
20145         local submount=${MOUNT}_$tdir
20146
20147         mkdir -p $submount || error "mkdir $submount failed"
20148         stack_trap "rmdir $submount"
20149
20150         FILESET="$fileset/$tdir" mount_client $submount ||
20151                 error "mount $dir failed"
20152         stack_trap "umount $submount"
20153
20154         local mdts=$(comma_list $(mdts_nodes))
20155
20156         local nrpcs
20157
20158         stat $submount > /dev/null
20159         cancel_lru_locks $MDC
20160         stat $submount > /dev/null
20161         stat $submount/$tfile > /dev/null
20162         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20163         stat $submount/$tfile > /dev/null
20164         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20165                 awk '/getattr/ {sum += $2} END {print sum}')
20166
20167         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20168 }
20169 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20170
20171 test_248a() {
20172         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20173         [ -z "$fast_read_sav" ] && skip "no fast read support"
20174
20175         # create a large file for fast read verification
20176         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20177
20178         # make sure the file is created correctly
20179         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20180                 { rm -f $DIR/$tfile; skip "file creation error"; }
20181
20182         echo "Test 1: verify that fast read is 4 times faster on cache read"
20183
20184         # small read with fast read enabled
20185         $LCTL set_param -n llite.*.fast_read=1
20186         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20187                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20188                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20189         # small read with fast read disabled
20190         $LCTL set_param -n llite.*.fast_read=0
20191         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20192                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20193                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20194
20195         # verify that fast read is 4 times faster for cache read
20196         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20197                 error_not_in_vm "fast read was not 4 times faster: " \
20198                            "$t_fast vs $t_slow"
20199
20200         echo "Test 2: verify the performance between big and small read"
20201         $LCTL set_param -n llite.*.fast_read=1
20202
20203         # 1k non-cache read
20204         cancel_lru_locks osc
20205         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20206                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20207                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20208
20209         # 1M non-cache read
20210         cancel_lru_locks osc
20211         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20212                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20213                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20214
20215         # verify that big IO is not 4 times faster than small IO
20216         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20217                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20218
20219         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20220         rm -f $DIR/$tfile
20221 }
20222 run_test 248a "fast read verification"
20223
20224 test_248b() {
20225         # Default short_io_bytes=16384, try both smaller and larger sizes.
20226         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20227         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20228         echo "bs=53248 count=113 normal buffered write"
20229         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20230                 error "dd of initial data file failed"
20231         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20232
20233         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20234         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20235                 error "dd with sync normal writes failed"
20236         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20237
20238         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20239         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20240                 error "dd with sync small writes failed"
20241         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20242
20243         cancel_lru_locks osc
20244
20245         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20246         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20247         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20248         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20249                 iflag=direct || error "dd with O_DIRECT small read failed"
20250         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20251         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20252                 error "compare $TMP/$tfile.1 failed"
20253
20254         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20255         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20256
20257         # just to see what the maximum tunable value is, and test parsing
20258         echo "test invalid parameter 2MB"
20259         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20260                 error "too-large short_io_bytes allowed"
20261         echo "test maximum parameter 512KB"
20262         # if we can set a larger short_io_bytes, run test regardless of version
20263         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20264                 # older clients may not allow setting it this large, that's OK
20265                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20266                         skip "Need at least client version 2.13.50"
20267                 error "medium short_io_bytes failed"
20268         fi
20269         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20270         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20271
20272         echo "test large parameter 64KB"
20273         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20274         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20275
20276         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20277         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20278                 error "dd with sync large writes failed"
20279         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20280
20281         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20282         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20283         num=$((113 * 4096 / PAGE_SIZE))
20284         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20285         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20286                 error "dd with O_DIRECT large writes failed"
20287         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20288                 error "compare $DIR/$tfile.3 failed"
20289
20290         cancel_lru_locks osc
20291
20292         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20293         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20294                 error "dd with O_DIRECT large read failed"
20295         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20296                 error "compare $TMP/$tfile.2 failed"
20297
20298         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20299         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20300                 error "dd with O_DIRECT large read failed"
20301         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20302                 error "compare $TMP/$tfile.3 failed"
20303 }
20304 run_test 248b "test short_io read and write for both small and large sizes"
20305
20306 test_249() { # LU-7890
20307         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20308                 skip "Need at least version 2.8.54"
20309
20310         rm -f $DIR/$tfile
20311         $LFS setstripe -c 1 $DIR/$tfile
20312         # Offset 2T == 4k * 512M
20313         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20314                 error "dd to 2T offset failed"
20315 }
20316 run_test 249 "Write above 2T file size"
20317
20318 test_250() {
20319         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20320          && skip "no 16TB file size limit on ZFS"
20321
20322         $LFS setstripe -c 1 $DIR/$tfile
20323         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20324         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20325         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20326         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20327                 conv=notrunc,fsync && error "append succeeded"
20328         return 0
20329 }
20330 run_test 250 "Write above 16T limit"
20331
20332 test_251() {
20333         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20334
20335         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20336         #Skip once - writing the first stripe will succeed
20337         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20338         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20339                 error "short write happened"
20340
20341         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20342         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20343                 error "short read happened"
20344
20345         rm -f $DIR/$tfile
20346 }
20347 run_test 251 "Handling short read and write correctly"
20348
20349 test_252() {
20350         remote_mds_nodsh && skip "remote MDS with nodsh"
20351         remote_ost_nodsh && skip "remote OST with nodsh"
20352         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20353                 skip_env "ldiskfs only test"
20354         fi
20355
20356         local tgt
20357         local dev
20358         local out
20359         local uuid
20360         local num
20361         local gen
20362
20363         # check lr_reader on OST0000
20364         tgt=ost1
20365         dev=$(facet_device $tgt)
20366         out=$(do_facet $tgt $LR_READER $dev)
20367         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20368         echo "$out"
20369         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20370         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20371                 error "Invalid uuid returned by $LR_READER on target $tgt"
20372         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20373
20374         # check lr_reader -c on MDT0000
20375         tgt=mds1
20376         dev=$(facet_device $tgt)
20377         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20378                 skip "$LR_READER does not support additional options"
20379         fi
20380         out=$(do_facet $tgt $LR_READER -c $dev)
20381         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20382         echo "$out"
20383         num=$(echo "$out" | grep -c "mdtlov")
20384         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20385                 error "Invalid number of mdtlov clients returned by $LR_READER"
20386         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20387
20388         # check lr_reader -cr on MDT0000
20389         out=$(do_facet $tgt $LR_READER -cr $dev)
20390         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20391         echo "$out"
20392         echo "$out" | grep -q "^reply_data:$" ||
20393                 error "$LR_READER should have returned 'reply_data' section"
20394         num=$(echo "$out" | grep -c "client_generation")
20395         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20396 }
20397 run_test 252 "check lr_reader tool"
20398
20399 test_253() {
20400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20401         remote_mds_nodsh && skip "remote MDS with nodsh"
20402         remote_mgs_nodsh && skip "remote MGS with nodsh"
20403
20404         local ostidx=0
20405         local rc=0
20406         local ost_name=$(ostname_from_index $ostidx)
20407
20408         # on the mdt's osc
20409         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20410         do_facet $SINGLEMDS $LCTL get_param -n \
20411                 osp.$mdtosc_proc1.reserved_mb_high ||
20412                 skip  "remote MDS does not support reserved_mb_high"
20413
20414         rm -rf $DIR/$tdir
20415         wait_mds_ost_sync
20416         wait_delete_completed
20417         mkdir $DIR/$tdir
20418
20419         pool_add $TESTNAME || error "Pool creation failed"
20420         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20421
20422         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20423                 error "Setstripe failed"
20424
20425         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20426
20427         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20428                     grep "watermarks")
20429         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20430
20431         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20432                         osp.$mdtosc_proc1.prealloc_status)
20433         echo "prealloc_status $oa_status"
20434
20435         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20436                 error "File creation should fail"
20437
20438         #object allocation was stopped, but we still able to append files
20439         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20440                 oflag=append || error "Append failed"
20441
20442         rm -f $DIR/$tdir/$tfile.0
20443
20444         # For this test, we want to delete the files we created to go out of
20445         # space but leave the watermark, so we remain nearly out of space
20446         ost_watermarks_enospc_delete_files $tfile $ostidx
20447
20448         wait_delete_completed
20449
20450         sleep_maxage
20451
20452         for i in $(seq 10 12); do
20453                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20454                         2>/dev/null || error "File creation failed after rm"
20455         done
20456
20457         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20458                         osp.$mdtosc_proc1.prealloc_status)
20459         echo "prealloc_status $oa_status"
20460
20461         if (( oa_status != 0 )); then
20462                 error "Object allocation still disable after rm"
20463         fi
20464 }
20465 run_test 253 "Check object allocation limit"
20466
20467 test_254() {
20468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20469         remote_mds_nodsh && skip "remote MDS with nodsh"
20470         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20471                 skip "MDS does not support changelog_size"
20472
20473         local cl_user
20474         local MDT0=$(facet_svc $SINGLEMDS)
20475
20476         changelog_register || error "changelog_register failed"
20477
20478         changelog_clear 0 || error "changelog_clear failed"
20479
20480         local size1=$(do_facet $SINGLEMDS \
20481                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20482         echo "Changelog size $size1"
20483
20484         rm -rf $DIR/$tdir
20485         $LFS mkdir -i 0 $DIR/$tdir
20486         # change something
20487         mkdir -p $DIR/$tdir/pics/2008/zachy
20488         touch $DIR/$tdir/pics/2008/zachy/timestamp
20489         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20490         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20491         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20492         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20493         rm $DIR/$tdir/pics/desktop.jpg
20494
20495         local size2=$(do_facet $SINGLEMDS \
20496                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20497         echo "Changelog size after work $size2"
20498
20499         (( $size2 > $size1 )) ||
20500                 error "new Changelog size=$size2 less than old size=$size1"
20501 }
20502 run_test 254 "Check changelog size"
20503
20504 ladvise_no_type()
20505 {
20506         local type=$1
20507         local file=$2
20508
20509         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20510                 awk -F: '{print $2}' | grep $type > /dev/null
20511         if [ $? -ne 0 ]; then
20512                 return 0
20513         fi
20514         return 1
20515 }
20516
20517 ladvise_no_ioctl()
20518 {
20519         local file=$1
20520
20521         lfs ladvise -a willread $file > /dev/null 2>&1
20522         if [ $? -eq 0 ]; then
20523                 return 1
20524         fi
20525
20526         lfs ladvise -a willread $file 2>&1 |
20527                 grep "Inappropriate ioctl for device" > /dev/null
20528         if [ $? -eq 0 ]; then
20529                 return 0
20530         fi
20531         return 1
20532 }
20533
20534 percent() {
20535         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20536 }
20537
20538 # run a random read IO workload
20539 # usage: random_read_iops <filename> <filesize> <iosize>
20540 random_read_iops() {
20541         local file=$1
20542         local fsize=$2
20543         local iosize=${3:-4096}
20544
20545         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20546                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20547 }
20548
20549 drop_file_oss_cache() {
20550         local file="$1"
20551         local nodes="$2"
20552
20553         $LFS ladvise -a dontneed $file 2>/dev/null ||
20554                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20555 }
20556
20557 ladvise_willread_performance()
20558 {
20559         local repeat=10
20560         local average_origin=0
20561         local average_cache=0
20562         local average_ladvise=0
20563
20564         for ((i = 1; i <= $repeat; i++)); do
20565                 echo "Iter $i/$repeat: reading without willread hint"
20566                 cancel_lru_locks osc
20567                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20568                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20569                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20570                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20571
20572                 cancel_lru_locks osc
20573                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20574                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20575                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20576
20577                 cancel_lru_locks osc
20578                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20579                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20580                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20581                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20582                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20583         done
20584         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20585         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20586         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20587
20588         speedup_cache=$(percent $average_cache $average_origin)
20589         speedup_ladvise=$(percent $average_ladvise $average_origin)
20590
20591         echo "Average uncached read: $average_origin"
20592         echo "Average speedup with OSS cached read: " \
20593                 "$average_cache = +$speedup_cache%"
20594         echo "Average speedup with ladvise willread: " \
20595                 "$average_ladvise = +$speedup_ladvise%"
20596
20597         local lowest_speedup=20
20598         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20599                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20600                         "got $average_cache%. Skipping ladvise willread check."
20601                 return 0
20602         fi
20603
20604         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20605         # it is still good to run until then to exercise 'ladvise willread'
20606         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20607                 [ "$ost1_FSTYPE" = "zfs" ] &&
20608                 echo "osd-zfs does not support dontneed or drop_caches" &&
20609                 return 0
20610
20611         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20612         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20613                 error_not_in_vm "Speedup with willread is less than " \
20614                         "$lowest_speedup%, got $average_ladvise%"
20615 }
20616
20617 test_255a() {
20618         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20619                 skip "lustre < 2.8.54 does not support ladvise "
20620         remote_ost_nodsh && skip "remote OST with nodsh"
20621
20622         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20623
20624         ladvise_no_type willread $DIR/$tfile &&
20625                 skip "willread ladvise is not supported"
20626
20627         ladvise_no_ioctl $DIR/$tfile &&
20628                 skip "ladvise ioctl is not supported"
20629
20630         local size_mb=100
20631         local size=$((size_mb * 1048576))
20632         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20633                 error "dd to $DIR/$tfile failed"
20634
20635         lfs ladvise -a willread $DIR/$tfile ||
20636                 error "Ladvise failed with no range argument"
20637
20638         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20639                 error "Ladvise failed with no -l or -e argument"
20640
20641         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20642                 error "Ladvise failed with only -e argument"
20643
20644         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20645                 error "Ladvise failed with only -l argument"
20646
20647         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20648                 error "End offset should not be smaller than start offset"
20649
20650         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20651                 error "End offset should not be equal to start offset"
20652
20653         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20654                 error "Ladvise failed with overflowing -s argument"
20655
20656         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20657                 error "Ladvise failed with overflowing -e argument"
20658
20659         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20660                 error "Ladvise failed with overflowing -l argument"
20661
20662         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20663                 error "Ladvise succeeded with conflicting -l and -e arguments"
20664
20665         echo "Synchronous ladvise should wait"
20666         local delay=4
20667 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20668         do_nodes $(comma_list $(osts_nodes)) \
20669                 $LCTL set_param fail_val=$delay fail_loc=0x237
20670
20671         local start_ts=$SECONDS
20672         lfs ladvise -a willread $DIR/$tfile ||
20673                 error "Ladvise failed with no range argument"
20674         local end_ts=$SECONDS
20675         local inteval_ts=$((end_ts - start_ts))
20676
20677         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20678                 error "Synchronous advice didn't wait reply"
20679         fi
20680
20681         echo "Asynchronous ladvise shouldn't wait"
20682         local start_ts=$SECONDS
20683         lfs ladvise -a willread -b $DIR/$tfile ||
20684                 error "Ladvise failed with no range argument"
20685         local end_ts=$SECONDS
20686         local inteval_ts=$((end_ts - start_ts))
20687
20688         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20689                 error "Asynchronous advice blocked"
20690         fi
20691
20692         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20693         ladvise_willread_performance
20694 }
20695 run_test 255a "check 'lfs ladvise -a willread'"
20696
20697 facet_meminfo() {
20698         local facet=$1
20699         local info=$2
20700
20701         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20702 }
20703
20704 test_255b() {
20705         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20706                 skip "lustre < 2.8.54 does not support ladvise "
20707         remote_ost_nodsh && skip "remote OST with nodsh"
20708
20709         lfs setstripe -c 1 -i 0 $DIR/$tfile
20710
20711         ladvise_no_type dontneed $DIR/$tfile &&
20712                 skip "dontneed ladvise is not supported"
20713
20714         ladvise_no_ioctl $DIR/$tfile &&
20715                 skip "ladvise ioctl is not supported"
20716
20717         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20718                 [ "$ost1_FSTYPE" = "zfs" ] &&
20719                 skip "zfs-osd does not support 'ladvise dontneed'"
20720
20721         local size_mb=100
20722         local size=$((size_mb * 1048576))
20723         # In order to prevent disturbance of other processes, only check 3/4
20724         # of the memory usage
20725         local kibibytes=$((size_mb * 1024 * 3 / 4))
20726
20727         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20728                 error "dd to $DIR/$tfile failed"
20729
20730         #force write to complete before dropping OST cache & checking memory
20731         sync
20732
20733         local total=$(facet_meminfo ost1 MemTotal)
20734         echo "Total memory: $total KiB"
20735
20736         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20737         local before_read=$(facet_meminfo ost1 Cached)
20738         echo "Cache used before read: $before_read KiB"
20739
20740         lfs ladvise -a willread $DIR/$tfile ||
20741                 error "Ladvise willread failed"
20742         local after_read=$(facet_meminfo ost1 Cached)
20743         echo "Cache used after read: $after_read KiB"
20744
20745         lfs ladvise -a dontneed $DIR/$tfile ||
20746                 error "Ladvise dontneed again failed"
20747         local no_read=$(facet_meminfo ost1 Cached)
20748         echo "Cache used after dontneed ladvise: $no_read KiB"
20749
20750         if [ $total -lt $((before_read + kibibytes)) ]; then
20751                 echo "Memory is too small, abort checking"
20752                 return 0
20753         fi
20754
20755         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20756                 error "Ladvise willread should use more memory" \
20757                         "than $kibibytes KiB"
20758         fi
20759
20760         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20761                 error "Ladvise dontneed should release more memory" \
20762                         "than $kibibytes KiB"
20763         fi
20764 }
20765 run_test 255b "check 'lfs ladvise -a dontneed'"
20766
20767 test_255c() {
20768         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20769                 skip "lustre < 2.10.50 does not support lockahead"
20770
20771         local ost1_imp=$(get_osc_import_name client ost1)
20772         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20773                          cut -d'.' -f2)
20774         local count
20775         local new_count
20776         local difference
20777         local i
20778         local rc
20779
20780         test_mkdir -p $DIR/$tdir
20781         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20782
20783         #test 10 returns only success/failure
20784         i=10
20785         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20786         rc=$?
20787         if [ $rc -eq 255 ]; then
20788                 error "Ladvise test${i} failed, ${rc}"
20789         fi
20790
20791         #test 11 counts lock enqueue requests, all others count new locks
20792         i=11
20793         count=$(do_facet ost1 \
20794                 $LCTL get_param -n ost.OSS.ost.stats)
20795         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20796
20797         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20798         rc=$?
20799         if [ $rc -eq 255 ]; then
20800                 error "Ladvise test${i} failed, ${rc}"
20801         fi
20802
20803         new_count=$(do_facet ost1 \
20804                 $LCTL get_param -n ost.OSS.ost.stats)
20805         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20806                    awk '{ print $2 }')
20807
20808         difference="$((new_count - count))"
20809         if [ $difference -ne $rc ]; then
20810                 error "Ladvise test${i}, bad enqueue count, returned " \
20811                       "${rc}, actual ${difference}"
20812         fi
20813
20814         for i in $(seq 12 21); do
20815                 # If we do not do this, we run the risk of having too many
20816                 # locks and starting lock cancellation while we are checking
20817                 # lock counts.
20818                 cancel_lru_locks osc
20819
20820                 count=$($LCTL get_param -n \
20821                        ldlm.namespaces.$imp_name.lock_unused_count)
20822
20823                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20824                 rc=$?
20825                 if [ $rc -eq 255 ]; then
20826                         error "Ladvise test ${i} failed, ${rc}"
20827                 fi
20828
20829                 new_count=$($LCTL get_param -n \
20830                        ldlm.namespaces.$imp_name.lock_unused_count)
20831                 difference="$((new_count - count))"
20832
20833                 # Test 15 output is divided by 100 to map down to valid return
20834                 if [ $i -eq 15 ]; then
20835                         rc="$((rc * 100))"
20836                 fi
20837
20838                 if [ $difference -ne $rc ]; then
20839                         error "Ladvise test ${i}, bad lock count, returned " \
20840                               "${rc}, actual ${difference}"
20841                 fi
20842         done
20843
20844         #test 22 returns only success/failure
20845         i=22
20846         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20847         rc=$?
20848         if [ $rc -eq 255 ]; then
20849                 error "Ladvise test${i} failed, ${rc}"
20850         fi
20851 }
20852 run_test 255c "suite of ladvise lockahead tests"
20853
20854 test_256() {
20855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20856         remote_mds_nodsh && skip "remote MDS with nodsh"
20857         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20858         changelog_users $SINGLEMDS | grep "^cl" &&
20859                 skip "active changelog user"
20860
20861         local cl_user
20862         local cat_sl
20863         local mdt_dev
20864
20865         mdt_dev=$(mdsdevname 1)
20866         echo $mdt_dev
20867
20868         changelog_register || error "changelog_register failed"
20869
20870         rm -rf $DIR/$tdir
20871         mkdir -p $DIR/$tdir
20872
20873         changelog_clear 0 || error "changelog_clear failed"
20874
20875         # change something
20876         touch $DIR/$tdir/{1..10}
20877
20878         # stop the MDT
20879         stop $SINGLEMDS || error "Fail to stop MDT"
20880
20881         # remount the MDT
20882
20883         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20884
20885         #after mount new plainllog is used
20886         touch $DIR/$tdir/{11..19}
20887         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20888         stack_trap "rm -f $tmpfile"
20889         cat_sl=$(do_facet $SINGLEMDS "sync; \
20890                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20891                  llog_reader $tmpfile | grep -c type=1064553b")
20892         do_facet $SINGLEMDS llog_reader $tmpfile
20893
20894         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20895
20896         changelog_clear 0 || error "changelog_clear failed"
20897
20898         cat_sl=$(do_facet $SINGLEMDS "sync; \
20899                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20900                  llog_reader $tmpfile | grep -c type=1064553b")
20901
20902         if (( cat_sl == 2 )); then
20903                 error "Empty plain llog was not deleted from changelog catalog"
20904         elif (( cat_sl != 1 )); then
20905                 error "Active plain llog shouldn't be deleted from catalog"
20906         fi
20907 }
20908 run_test 256 "Check llog delete for empty and not full state"
20909
20910 test_257() {
20911         remote_mds_nodsh && skip "remote MDS with nodsh"
20912         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20913                 skip "Need MDS version at least 2.8.55"
20914
20915         test_mkdir $DIR/$tdir
20916
20917         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20918                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20919         stat $DIR/$tdir
20920
20921 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20922         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20923         local facet=mds$((mdtidx + 1))
20924         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20925         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20926
20927         stop $facet || error "stop MDS failed"
20928         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20929                 error "start MDS fail"
20930         wait_recovery_complete $facet
20931 }
20932 run_test 257 "xattr locks are not lost"
20933
20934 # Verify we take the i_mutex when security requires it
20935 test_258a() {
20936 #define OBD_FAIL_IMUTEX_SEC 0x141c
20937         $LCTL set_param fail_loc=0x141c
20938         touch $DIR/$tfile
20939         chmod u+s $DIR/$tfile
20940         chmod a+rwx $DIR/$tfile
20941         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20942         RC=$?
20943         if [ $RC -ne 0 ]; then
20944                 error "error, failed to take i_mutex, rc=$?"
20945         fi
20946         rm -f $DIR/$tfile
20947 }
20948 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20949
20950 # Verify we do NOT take the i_mutex in the normal case
20951 test_258b() {
20952 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20953         $LCTL set_param fail_loc=0x141d
20954         touch $DIR/$tfile
20955         chmod a+rwx $DIR
20956         chmod a+rw $DIR/$tfile
20957         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20958         RC=$?
20959         if [ $RC -ne 0 ]; then
20960                 error "error, took i_mutex unnecessarily, rc=$?"
20961         fi
20962         rm -f $DIR/$tfile
20963
20964 }
20965 run_test 258b "verify i_mutex security behavior"
20966
20967 test_259() {
20968         local file=$DIR/$tfile
20969         local before
20970         local after
20971
20972         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20973
20974         stack_trap "rm -f $file" EXIT
20975
20976         wait_delete_completed
20977         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20978         echo "before: $before"
20979
20980         $LFS setstripe -i 0 -c 1 $file
20981         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20982         sync_all_data
20983         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20984         echo "after write: $after"
20985
20986 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20987         do_facet ost1 $LCTL set_param fail_loc=0x2301
20988         $TRUNCATE $file 0
20989         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20990         echo "after truncate: $after"
20991
20992         stop ost1
20993         do_facet ost1 $LCTL set_param fail_loc=0
20994         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20995         sleep 2
20996         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20997         echo "after restart: $after"
20998         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20999                 error "missing truncate?"
21000
21001         return 0
21002 }
21003 run_test 259 "crash at delayed truncate"
21004
21005 test_260() {
21006 #define OBD_FAIL_MDC_CLOSE               0x806
21007         $LCTL set_param fail_loc=0x80000806
21008         touch $DIR/$tfile
21009
21010 }
21011 run_test 260 "Check mdc_close fail"
21012
21013 ### Data-on-MDT sanity tests ###
21014 test_270a() {
21015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21016                 skip "Need MDS version at least 2.10.55 for DoM"
21017
21018         # create DoM file
21019         local dom=$DIR/$tdir/dom_file
21020         local tmp=$DIR/$tdir/tmp_file
21021
21022         mkdir -p $DIR/$tdir
21023
21024         # basic checks for DoM component creation
21025         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21026                 error "Can set MDT layout to non-first entry"
21027
21028         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21029                 error "Can define multiple entries as MDT layout"
21030
21031         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21032
21033         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21034         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21035         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21036
21037         local mdtidx=$($LFS getstripe -m $dom)
21038         local mdtname=MDT$(printf %04x $mdtidx)
21039         local facet=mds$((mdtidx + 1))
21040         local space_check=1
21041
21042         # Skip free space checks with ZFS
21043         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21044
21045         # write
21046         sync
21047         local size_tmp=$((65536 * 3))
21048         local mdtfree1=$(do_facet $facet \
21049                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21050
21051         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21052         # check also direct IO along write
21053         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21054         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21055         sync
21056         cmp $tmp $dom || error "file data is different"
21057         [ $(stat -c%s $dom) == $size_tmp ] ||
21058                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21059         if [ $space_check == 1 ]; then
21060                 local mdtfree2=$(do_facet $facet \
21061                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21062
21063                 # increase in usage from by $size_tmp
21064                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21065                         error "MDT free space wrong after write: " \
21066                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21067         fi
21068
21069         # truncate
21070         local size_dom=10000
21071
21072         $TRUNCATE $dom $size_dom
21073         [ $(stat -c%s $dom) == $size_dom ] ||
21074                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21075         if [ $space_check == 1 ]; then
21076                 mdtfree1=$(do_facet $facet \
21077                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21078                 # decrease in usage from $size_tmp to new $size_dom
21079                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21080                   $(((size_tmp - size_dom) / 1024)) ] ||
21081                         error "MDT free space is wrong after truncate: " \
21082                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21083         fi
21084
21085         # append
21086         cat $tmp >> $dom
21087         sync
21088         size_dom=$((size_dom + size_tmp))
21089         [ $(stat -c%s $dom) == $size_dom ] ||
21090                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21091         if [ $space_check == 1 ]; then
21092                 mdtfree2=$(do_facet $facet \
21093                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21094                 # increase in usage by $size_tmp from previous
21095                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21096                         error "MDT free space is wrong after append: " \
21097                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21098         fi
21099
21100         # delete
21101         rm $dom
21102         if [ $space_check == 1 ]; then
21103                 mdtfree1=$(do_facet $facet \
21104                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21105                 # decrease in usage by $size_dom from previous
21106                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21107                         error "MDT free space is wrong after removal: " \
21108                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21109         fi
21110
21111         # combined striping
21112         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21113                 error "Can't create DoM + OST striping"
21114
21115         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21116         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21117         # check also direct IO along write
21118         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21119         sync
21120         cmp $tmp $dom || error "file data is different"
21121         [ $(stat -c%s $dom) == $size_tmp ] ||
21122                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21123         rm $dom $tmp
21124
21125         return 0
21126 }
21127 run_test 270a "DoM: basic functionality tests"
21128
21129 test_270b() {
21130         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21131                 skip "Need MDS version at least 2.10.55"
21132
21133         local dom=$DIR/$tdir/dom_file
21134         local max_size=1048576
21135
21136         mkdir -p $DIR/$tdir
21137         $LFS setstripe -E $max_size -L mdt $dom
21138
21139         # truncate over the limit
21140         $TRUNCATE $dom $(($max_size + 1)) &&
21141                 error "successful truncate over the maximum size"
21142         # write over the limit
21143         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21144                 error "successful write over the maximum size"
21145         # append over the limit
21146         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21147         echo "12345" >> $dom && error "successful append over the maximum size"
21148         rm $dom
21149
21150         return 0
21151 }
21152 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21153
21154 test_270c() {
21155         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21156                 skip "Need MDS version at least 2.10.55"
21157
21158         mkdir -p $DIR/$tdir
21159         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21160
21161         # check files inherit DoM EA
21162         touch $DIR/$tdir/first
21163         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21164                 error "bad pattern"
21165         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21166                 error "bad stripe count"
21167         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21168                 error "bad stripe size"
21169
21170         # check directory inherits DoM EA and uses it as default
21171         mkdir $DIR/$tdir/subdir
21172         touch $DIR/$tdir/subdir/second
21173         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21174                 error "bad pattern in sub-directory"
21175         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21176                 error "bad stripe count in sub-directory"
21177         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21178                 error "bad stripe size in sub-directory"
21179         return 0
21180 }
21181 run_test 270c "DoM: DoM EA inheritance tests"
21182
21183 test_270d() {
21184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21185                 skip "Need MDS version at least 2.10.55"
21186
21187         mkdir -p $DIR/$tdir
21188         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21189
21190         # inherit default DoM striping
21191         mkdir $DIR/$tdir/subdir
21192         touch $DIR/$tdir/subdir/f1
21193
21194         # change default directory striping
21195         $LFS setstripe -c 1 $DIR/$tdir/subdir
21196         touch $DIR/$tdir/subdir/f2
21197         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21198                 error "wrong default striping in file 2"
21199         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21200                 error "bad pattern in file 2"
21201         return 0
21202 }
21203 run_test 270d "DoM: change striping from DoM to RAID0"
21204
21205 test_270e() {
21206         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21207                 skip "Need MDS version at least 2.10.55"
21208
21209         mkdir -p $DIR/$tdir/dom
21210         mkdir -p $DIR/$tdir/norm
21211         DOMFILES=20
21212         NORMFILES=10
21213         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21214         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21215
21216         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21217         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21218
21219         # find DoM files by layout
21220         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21221         [ $NUM -eq  $DOMFILES ] ||
21222                 error "lfs find -L: found $NUM, expected $DOMFILES"
21223         echo "Test 1: lfs find 20 DOM files by layout: OK"
21224
21225         # there should be 1 dir with default DOM striping
21226         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21227         [ $NUM -eq  1 ] ||
21228                 error "lfs find -L: found $NUM, expected 1 dir"
21229         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21230
21231         # find DoM files by stripe size
21232         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21233         [ $NUM -eq  $DOMFILES ] ||
21234                 error "lfs find -S: found $NUM, expected $DOMFILES"
21235         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21236
21237         # find files by stripe offset except DoM files
21238         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21239         [ $NUM -eq  $NORMFILES ] ||
21240                 error "lfs find -i: found $NUM, expected $NORMFILES"
21241         echo "Test 5: lfs find no DOM files by stripe index: OK"
21242         return 0
21243 }
21244 run_test 270e "DoM: lfs find with DoM files test"
21245
21246 test_270f() {
21247         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21248                 skip "Need MDS version at least 2.10.55"
21249
21250         local mdtname=${FSNAME}-MDT0000-mdtlov
21251         local dom=$DIR/$tdir/dom_file
21252         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21253                                                 lod.$mdtname.dom_stripesize)
21254         local dom_limit=131072
21255
21256         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21257         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21258                                                 lod.$mdtname.dom_stripesize)
21259         [ ${dom_limit} -eq ${dom_current} ] ||
21260                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21261
21262         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21263         $LFS setstripe -d $DIR/$tdir
21264         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21265                 error "Can't set directory default striping"
21266
21267         # exceed maximum stripe size
21268         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21269                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21270         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21271                 error "Able to create DoM component size more than LOD limit"
21272
21273         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21274         dom_current=$(do_facet mds1 $LCTL get_param -n \
21275                                                 lod.$mdtname.dom_stripesize)
21276         [ 0 -eq ${dom_current} ] ||
21277                 error "Can't set zero DoM stripe limit"
21278         rm $dom
21279
21280         # attempt to create DoM file on server with disabled DoM should
21281         # remove DoM entry from layout and be succeed
21282         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21283                 error "Can't create DoM file (DoM is disabled)"
21284         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21285                 error "File has DoM component while DoM is disabled"
21286         rm $dom
21287
21288         # attempt to create DoM file with only DoM stripe should return error
21289         $LFS setstripe -E $dom_limit -L mdt $dom &&
21290                 error "Able to create DoM-only file while DoM is disabled"
21291
21292         # too low values to be aligned with smallest stripe size 64K
21293         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21294         dom_current=$(do_facet mds1 $LCTL get_param -n \
21295                                                 lod.$mdtname.dom_stripesize)
21296         [ 30000 -eq ${dom_current} ] &&
21297                 error "Can set too small DoM stripe limit"
21298
21299         # 64K is a minimal stripe size in Lustre, expect limit of that size
21300         [ 65536 -eq ${dom_current} ] ||
21301                 error "Limit is not set to 64K but ${dom_current}"
21302
21303         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21304         dom_current=$(do_facet mds1 $LCTL get_param -n \
21305                                                 lod.$mdtname.dom_stripesize)
21306         echo $dom_current
21307         [ 2147483648 -eq ${dom_current} ] &&
21308                 error "Can set too large DoM stripe limit"
21309
21310         do_facet mds1 $LCTL set_param -n \
21311                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21312         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21313                 error "Can't create DoM component size after limit change"
21314         do_facet mds1 $LCTL set_param -n \
21315                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21316         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21317                 error "Can't create DoM file after limit decrease"
21318         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21319                 error "Can create big DoM component after limit decrease"
21320         touch ${dom}_def ||
21321                 error "Can't create file with old default layout"
21322
21323         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21324         return 0
21325 }
21326 run_test 270f "DoM: maximum DoM stripe size checks"
21327
21328 test_270g() {
21329         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21330                 skip "Need MDS version at least 2.13.52"
21331         local dom=$DIR/$tdir/$tfile
21332
21333         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21334         local lodname=${FSNAME}-MDT0000-mdtlov
21335
21336         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21337         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21338         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21339         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21340
21341         local dom_limit=1024
21342         local dom_threshold="50%"
21343
21344         $LFS setstripe -d $DIR/$tdir
21345         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21346                 error "Can't set directory default striping"
21347
21348         do_facet mds1 $LCTL set_param -n \
21349                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21350         # set 0 threshold and create DOM file to change tunable stripesize
21351         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21352         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21353                 error "Failed to create $dom file"
21354         # now tunable dom_cur_stripesize should reach maximum
21355         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21356                                         lod.${lodname}.dom_stripesize_cur_kb)
21357         [[ $dom_current == $dom_limit ]] ||
21358                 error "Current DOM stripesize is not maximum"
21359         rm $dom
21360
21361         # set threshold for further tests
21362         do_facet mds1 $LCTL set_param -n \
21363                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21364         echo "DOM threshold is $dom_threshold free space"
21365         local dom_def
21366         local dom_set
21367         # Spoof bfree to exceed threshold
21368         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21369         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21370         for spfree in 40 20 0 15 30 55; do
21371                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21372                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21373                         error "Failed to create $dom file"
21374                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21375                                         lod.${lodname}.dom_stripesize_cur_kb)
21376                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21377                 [[ $dom_def != $dom_current ]] ||
21378                         error "Default stripe size was not changed"
21379                 if [[ $spfree > 0 ]] ; then
21380                         dom_set=$($LFS getstripe -S $dom)
21381                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21382                                 error "DOM component size is still old"
21383                 else
21384                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21385                                 error "DoM component is set with no free space"
21386                 fi
21387                 rm $dom
21388                 dom_current=$dom_def
21389         done
21390 }
21391 run_test 270g "DoM: default DoM stripe size depends on free space"
21392
21393 test_270h() {
21394         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21395                 skip "Need MDS version at least 2.13.53"
21396
21397         local mdtname=${FSNAME}-MDT0000-mdtlov
21398         local dom=$DIR/$tdir/$tfile
21399         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21400
21401         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21402         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21403
21404         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21405         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21406                 error "can't create OST file"
21407         # mirrored file with DOM entry in the second mirror
21408         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21409                 error "can't create mirror with DoM component"
21410
21411         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21412
21413         # DOM component in the middle and has other enries in the same mirror,
21414         # should succeed but lost DoM component
21415         $LFS setstripe --copy=${dom}_1 $dom ||
21416                 error "Can't create file from OST|DOM mirror layout"
21417         # check new file has no DoM layout after all
21418         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21419                 error "File has DoM component while DoM is disabled"
21420 }
21421 run_test 270h "DoM: DoM stripe removal when disabled on server"
21422
21423 test_271a() {
21424         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21425                 skip "Need MDS version at least 2.10.55"
21426
21427         local dom=$DIR/$tdir/dom
21428
21429         mkdir -p $DIR/$tdir
21430
21431         $LFS setstripe -E 1024K -L mdt $dom
21432
21433         lctl set_param -n mdc.*.stats=clear
21434         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21435         cat $dom > /dev/null
21436         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21437         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21438         ls $dom
21439         rm -f $dom
21440 }
21441 run_test 271a "DoM: data is cached for read after write"
21442
21443 test_271b() {
21444         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21445                 skip "Need MDS version at least 2.10.55"
21446
21447         local dom=$DIR/$tdir/dom
21448
21449         mkdir -p $DIR/$tdir
21450
21451         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21452
21453         lctl set_param -n mdc.*.stats=clear
21454         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21455         cancel_lru_locks mdc
21456         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21457         # second stat to check size is cached on client
21458         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21459         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21460         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21461         rm -f $dom
21462 }
21463 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21464
21465 test_271ba() {
21466         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21467                 skip "Need MDS version at least 2.10.55"
21468
21469         local dom=$DIR/$tdir/dom
21470
21471         mkdir -p $DIR/$tdir
21472
21473         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21474
21475         lctl set_param -n mdc.*.stats=clear
21476         lctl set_param -n osc.*.stats=clear
21477         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21478         cancel_lru_locks mdc
21479         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21480         # second stat to check size is cached on client
21481         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21482         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21483         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21484         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21485         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21486         rm -f $dom
21487 }
21488 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21489
21490
21491 get_mdc_stats() {
21492         local mdtidx=$1
21493         local param=$2
21494         local mdt=MDT$(printf %04x $mdtidx)
21495
21496         if [ -z $param ]; then
21497                 lctl get_param -n mdc.*$mdt*.stats
21498         else
21499                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21500         fi
21501 }
21502
21503 test_271c() {
21504         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21505                 skip "Need MDS version at least 2.10.55"
21506
21507         local dom=$DIR/$tdir/dom
21508
21509         mkdir -p $DIR/$tdir
21510
21511         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21512
21513         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21514         local facet=mds$((mdtidx + 1))
21515
21516         cancel_lru_locks mdc
21517         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21518         createmany -o $dom 1000
21519         lctl set_param -n mdc.*.stats=clear
21520         smalliomany -w $dom 1000 200
21521         get_mdc_stats $mdtidx
21522         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21523         # Each file has 1 open, 1 IO enqueues, total 2000
21524         # but now we have also +1 getxattr for security.capability, total 3000
21525         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21526         unlinkmany $dom 1000
21527
21528         cancel_lru_locks mdc
21529         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21530         createmany -o $dom 1000
21531         lctl set_param -n mdc.*.stats=clear
21532         smalliomany -w $dom 1000 200
21533         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21534         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21535         # for OPEN and IO lock.
21536         [ $((enq - enq_2)) -ge 1000 ] ||
21537                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21538         unlinkmany $dom 1000
21539         return 0
21540 }
21541 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21542
21543 cleanup_271def_tests() {
21544         trap 0
21545         rm -f $1
21546 }
21547
21548 test_271d() {
21549         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21550                 skip "Need MDS version at least 2.10.57"
21551
21552         local dom=$DIR/$tdir/dom
21553         local tmp=$TMP/$tfile
21554         trap "cleanup_271def_tests $tmp" EXIT
21555
21556         mkdir -p $DIR/$tdir
21557
21558         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21559
21560         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21561
21562         cancel_lru_locks mdc
21563         dd if=/dev/urandom of=$tmp bs=1000 count=1
21564         dd if=$tmp of=$dom bs=1000 count=1
21565         cancel_lru_locks mdc
21566
21567         cat /etc/hosts >> $tmp
21568         lctl set_param -n mdc.*.stats=clear
21569
21570         # append data to the same file it should update local page
21571         echo "Append to the same page"
21572         cat /etc/hosts >> $dom
21573         local num=$(get_mdc_stats $mdtidx ost_read)
21574         local ra=$(get_mdc_stats $mdtidx req_active)
21575         local rw=$(get_mdc_stats $mdtidx req_waittime)
21576
21577         [ -z $num ] || error "$num READ RPC occured"
21578         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21579         echo "... DONE"
21580
21581         # compare content
21582         cmp $tmp $dom || error "file miscompare"
21583
21584         cancel_lru_locks mdc
21585         lctl set_param -n mdc.*.stats=clear
21586
21587         echo "Open and read file"
21588         cat $dom > /dev/null
21589         local num=$(get_mdc_stats $mdtidx ost_read)
21590         local ra=$(get_mdc_stats $mdtidx req_active)
21591         local rw=$(get_mdc_stats $mdtidx req_waittime)
21592
21593         [ -z $num ] || error "$num READ RPC occured"
21594         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21595         echo "... DONE"
21596
21597         # compare content
21598         cmp $tmp $dom || error "file miscompare"
21599
21600         return 0
21601 }
21602 run_test 271d "DoM: read on open (1K file in reply buffer)"
21603
21604 test_271f() {
21605         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21606                 skip "Need MDS version at least 2.10.57"
21607
21608         local dom=$DIR/$tdir/dom
21609         local tmp=$TMP/$tfile
21610         trap "cleanup_271def_tests $tmp" EXIT
21611
21612         mkdir -p $DIR/$tdir
21613
21614         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21615
21616         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21617
21618         cancel_lru_locks mdc
21619         dd if=/dev/urandom of=$tmp bs=265000 count=1
21620         dd if=$tmp of=$dom bs=265000 count=1
21621         cancel_lru_locks mdc
21622         cat /etc/hosts >> $tmp
21623         lctl set_param -n mdc.*.stats=clear
21624
21625         echo "Append to the same page"
21626         cat /etc/hosts >> $dom
21627         local num=$(get_mdc_stats $mdtidx ost_read)
21628         local ra=$(get_mdc_stats $mdtidx req_active)
21629         local rw=$(get_mdc_stats $mdtidx req_waittime)
21630
21631         [ -z $num ] || error "$num READ RPC occured"
21632         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21633         echo "... DONE"
21634
21635         # compare content
21636         cmp $tmp $dom || error "file miscompare"
21637
21638         cancel_lru_locks mdc
21639         lctl set_param -n mdc.*.stats=clear
21640
21641         echo "Open and read file"
21642         cat $dom > /dev/null
21643         local num=$(get_mdc_stats $mdtidx ost_read)
21644         local ra=$(get_mdc_stats $mdtidx req_active)
21645         local rw=$(get_mdc_stats $mdtidx req_waittime)
21646
21647         [ -z $num ] && num=0
21648         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21649         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21650         echo "... DONE"
21651
21652         # compare content
21653         cmp $tmp $dom || error "file miscompare"
21654
21655         return 0
21656 }
21657 run_test 271f "DoM: read on open (200K file and read tail)"
21658
21659 test_271g() {
21660         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21661                 skip "Skipping due to old client or server version"
21662
21663         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21664         # to get layout
21665         $CHECKSTAT -t file $DIR1/$tfile
21666
21667         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21668         MULTIOP_PID=$!
21669         sleep 1
21670         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21671         $LCTL set_param fail_loc=0x80000314
21672         rm $DIR1/$tfile || error "Unlink fails"
21673         RC=$?
21674         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21675         [ $RC -eq 0 ] || error "Failed write to stale object"
21676 }
21677 run_test 271g "Discard DoM data vs client flush race"
21678
21679 test_272a() {
21680         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21681                 skip "Need MDS version at least 2.11.50"
21682
21683         local dom=$DIR/$tdir/dom
21684         mkdir -p $DIR/$tdir
21685
21686         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21687         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21688                 error "failed to write data into $dom"
21689         local old_md5=$(md5sum $dom)
21690
21691         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21692                 error "failed to migrate to the same DoM component"
21693
21694         local new_md5=$(md5sum $dom)
21695
21696         [ "$old_md5" == "$new_md5" ] ||
21697                 error "md5sum differ: $old_md5, $new_md5"
21698
21699         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21700                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21701 }
21702 run_test 272a "DoM migration: new layout with the same DOM component"
21703
21704 test_272b() {
21705         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21706                 skip "Need MDS version at least 2.11.50"
21707
21708         local dom=$DIR/$tdir/dom
21709         mkdir -p $DIR/$tdir
21710         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21711
21712         local mdtidx=$($LFS getstripe -m $dom)
21713         local mdtname=MDT$(printf %04x $mdtidx)
21714         local facet=mds$((mdtidx + 1))
21715
21716         local mdtfree1=$(do_facet $facet \
21717                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21718         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21719                 error "failed to write data into $dom"
21720         local old_md5=$(md5sum $dom)
21721         cancel_lru_locks mdc
21722         local mdtfree1=$(do_facet $facet \
21723                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21724
21725         $LFS migrate -c2 $dom ||
21726                 error "failed to migrate to the new composite layout"
21727         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21728                 error "MDT stripe was not removed"
21729
21730         cancel_lru_locks mdc
21731         local new_md5=$(md5sum $dom)
21732         [ "$old_md5" == "$new_md5" ] ||
21733                 error "$old_md5 != $new_md5"
21734
21735         # Skip free space checks with ZFS
21736         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21737                 local mdtfree2=$(do_facet $facet \
21738                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21739                 [ $mdtfree2 -gt $mdtfree1 ] ||
21740                         error "MDT space is not freed after migration"
21741         fi
21742         return 0
21743 }
21744 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21745
21746 test_272c() {
21747         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21748                 skip "Need MDS version at least 2.11.50"
21749
21750         local dom=$DIR/$tdir/$tfile
21751         mkdir -p $DIR/$tdir
21752         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21753
21754         local mdtidx=$($LFS getstripe -m $dom)
21755         local mdtname=MDT$(printf %04x $mdtidx)
21756         local facet=mds$((mdtidx + 1))
21757
21758         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21759                 error "failed to write data into $dom"
21760         local old_md5=$(md5sum $dom)
21761         cancel_lru_locks mdc
21762         local mdtfree1=$(do_facet $facet \
21763                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21764
21765         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21766                 error "failed to migrate to the new composite layout"
21767         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21768                 error "MDT stripe was not removed"
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         # Skip free space checks with ZFS
21776         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21777                 local mdtfree2=$(do_facet $facet \
21778                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21779                 [ $mdtfree2 -gt $mdtfree1 ] ||
21780                         error "MDS space is not freed after migration"
21781         fi
21782         return 0
21783 }
21784 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21785
21786 test_272d() {
21787         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21788                 skip "Need MDS version at least 2.12.55"
21789
21790         local dom=$DIR/$tdir/$tfile
21791         mkdir -p $DIR/$tdir
21792         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21793
21794         local mdtidx=$($LFS getstripe -m $dom)
21795         local mdtname=MDT$(printf %04x $mdtidx)
21796         local facet=mds$((mdtidx + 1))
21797
21798         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21799                 error "failed to write data into $dom"
21800         local old_md5=$(md5sum $dom)
21801         cancel_lru_locks mdc
21802         local mdtfree1=$(do_facet $facet \
21803                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21804
21805         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21806                 error "failed mirroring to the new composite layout"
21807         $LFS mirror resync $dom ||
21808                 error "failed mirror resync"
21809         $LFS mirror split --mirror-id 1 -d $dom ||
21810                 error "failed mirror split"
21811
21812         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21813                 error "MDT stripe was not removed"
21814
21815         cancel_lru_locks mdc
21816         local new_md5=$(md5sum $dom)
21817         [ "$old_md5" == "$new_md5" ] ||
21818                 error "$old_md5 != $new_md5"
21819
21820         # Skip free space checks with ZFS
21821         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21822                 local mdtfree2=$(do_facet $facet \
21823                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21824                 [ $mdtfree2 -gt $mdtfree1 ] ||
21825                         error "MDS space is not freed after DOM mirror deletion"
21826         fi
21827         return 0
21828 }
21829 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21830
21831 test_272e() {
21832         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21833                 skip "Need MDS version at least 2.12.55"
21834
21835         local dom=$DIR/$tdir/$tfile
21836         mkdir -p $DIR/$tdir
21837         $LFS setstripe -c 2 $dom
21838
21839         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21840                 error "failed to write data into $dom"
21841         local old_md5=$(md5sum $dom)
21842         cancel_lru_locks mdc
21843
21844         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21845                 error "failed mirroring to the DOM layout"
21846         $LFS mirror resync $dom ||
21847                 error "failed mirror resync"
21848         $LFS mirror split --mirror-id 1 -d $dom ||
21849                 error "failed mirror split"
21850
21851         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21852                 error "MDT stripe was not removed"
21853
21854         cancel_lru_locks mdc
21855         local new_md5=$(md5sum $dom)
21856         [ "$old_md5" == "$new_md5" ] ||
21857                 error "$old_md5 != $new_md5"
21858
21859         return 0
21860 }
21861 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21862
21863 test_272f() {
21864         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21865                 skip "Need MDS version at least 2.12.55"
21866
21867         local dom=$DIR/$tdir/$tfile
21868         mkdir -p $DIR/$tdir
21869         $LFS setstripe -c 2 $dom
21870
21871         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21872                 error "failed to write data into $dom"
21873         local old_md5=$(md5sum $dom)
21874         cancel_lru_locks mdc
21875
21876         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21877                 error "failed migrating to the DOM file"
21878
21879         cancel_lru_locks mdc
21880         local new_md5=$(md5sum $dom)
21881         [ "$old_md5" != "$new_md5" ] &&
21882                 error "$old_md5 != $new_md5"
21883
21884         return 0
21885 }
21886 run_test 272f "DoM migration: OST-striped file to DOM file"
21887
21888 test_273a() {
21889         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21890                 skip "Need MDS version at least 2.11.50"
21891
21892         # Layout swap cannot be done if either file has DOM component,
21893         # this will never be supported, migration should be used instead
21894
21895         local dom=$DIR/$tdir/$tfile
21896         mkdir -p $DIR/$tdir
21897
21898         $LFS setstripe -c2 ${dom}_plain
21899         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21900         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21901                 error "can swap layout with DoM component"
21902         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21903                 error "can swap layout with DoM component"
21904
21905         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21906         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21907                 error "can swap layout with DoM component"
21908         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21909                 error "can swap layout with DoM component"
21910         return 0
21911 }
21912 run_test 273a "DoM: layout swapping should fail with DOM"
21913
21914 test_273b() {
21915         mkdir -p $DIR/$tdir
21916         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21917
21918 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21919         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21920
21921         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21922 }
21923 run_test 273b "DoM: race writeback and object destroy"
21924
21925 test_275() {
21926         remote_ost_nodsh && skip "remote OST with nodsh"
21927         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21928                 skip "Need OST version >= 2.10.57"
21929
21930         local file=$DIR/$tfile
21931         local oss
21932
21933         oss=$(comma_list $(osts_nodes))
21934
21935         dd if=/dev/urandom of=$file bs=1M count=2 ||
21936                 error "failed to create a file"
21937         cancel_lru_locks osc
21938
21939         #lock 1
21940         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21941                 error "failed to read a file"
21942
21943 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21944         $LCTL set_param fail_loc=0x8000031f
21945
21946         cancel_lru_locks osc &
21947         sleep 1
21948
21949 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21950         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21951         #IO takes another lock, but matches the PENDING one
21952         #and places it to the IO RPC
21953         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21954                 error "failed to read a file with PENDING lock"
21955 }
21956 run_test 275 "Read on a canceled duplicate lock"
21957
21958 test_276() {
21959         remote_ost_nodsh && skip "remote OST with nodsh"
21960         local pid
21961
21962         do_facet ost1 "(while true; do \
21963                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21964                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21965         pid=$!
21966
21967         for LOOP in $(seq 20); do
21968                 stop ost1
21969                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21970         done
21971         kill -9 $pid
21972         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21973                 rm $TMP/sanity_276_pid"
21974 }
21975 run_test 276 "Race between mount and obd_statfs"
21976
21977 test_277() {
21978         $LCTL set_param ldlm.namespaces.*.lru_size=0
21979         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21980         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21981                         grep ^used_mb | awk '{print $2}')
21982         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21983         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21984                 oflag=direct conv=notrunc
21985         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21986                         grep ^used_mb | awk '{print $2}')
21987         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21988 }
21989 run_test 277 "Direct IO shall drop page cache"
21990
21991 test_278() {
21992         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21993         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21994         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21995                 skip "needs the same host for mdt1 mdt2" && return
21996
21997         local pid1
21998         local pid2
21999
22000 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22001         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22002         stop mds2 &
22003         pid2=$!
22004
22005         stop mds1
22006
22007         echo "Starting MDTs"
22008         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22009         wait $pid2
22010 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22011 #will return NULL
22012         do_facet mds2 $LCTL set_param fail_loc=0
22013
22014         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22015         wait_recovery_complete mds2
22016 }
22017 run_test 278 "Race starting MDS between MDTs stop/start"
22018
22019 test_280() {
22020         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22021                 skip "Need MGS version at least 2.13.52"
22022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22023         combined_mgs_mds || skip "needs combined MGS/MDT"
22024
22025         umount_client $MOUNT
22026 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22027         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22028
22029         mount_client $MOUNT &
22030         sleep 1
22031         stop mgs || error "stop mgs failed"
22032         #for a race mgs would crash
22033         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22034         # make sure we unmount client before remounting
22035         wait
22036         umount_client $MOUNT
22037         mount_client $MOUNT || error "mount client failed"
22038 }
22039 run_test 280 "Race between MGS umount and client llog processing"
22040
22041 cleanup_test_300() {
22042         trap 0
22043         umask $SAVE_UMASK
22044 }
22045 test_striped_dir() {
22046         local mdt_index=$1
22047         local stripe_count
22048         local stripe_index
22049
22050         mkdir -p $DIR/$tdir
22051
22052         SAVE_UMASK=$(umask)
22053         trap cleanup_test_300 RETURN EXIT
22054
22055         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22056                                                 $DIR/$tdir/striped_dir ||
22057                 error "set striped dir error"
22058
22059         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22060         [ "$mode" = "755" ] || error "expect 755 got $mode"
22061
22062         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22063                 error "getdirstripe failed"
22064         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22065         if [ "$stripe_count" != "2" ]; then
22066                 error "1:stripe_count is $stripe_count, expect 2"
22067         fi
22068         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22069         if [ "$stripe_count" != "2" ]; then
22070                 error "2:stripe_count is $stripe_count, expect 2"
22071         fi
22072
22073         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22074         if [ "$stripe_index" != "$mdt_index" ]; then
22075                 error "stripe_index is $stripe_index, expect $mdt_index"
22076         fi
22077
22078         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22079                 error "nlink error after create striped dir"
22080
22081         mkdir $DIR/$tdir/striped_dir/a
22082         mkdir $DIR/$tdir/striped_dir/b
22083
22084         stat $DIR/$tdir/striped_dir/a ||
22085                 error "create dir under striped dir failed"
22086         stat $DIR/$tdir/striped_dir/b ||
22087                 error "create dir under striped dir failed"
22088
22089         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22090                 error "nlink error after mkdir"
22091
22092         rmdir $DIR/$tdir/striped_dir/a
22093         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22094                 error "nlink error after rmdir"
22095
22096         rmdir $DIR/$tdir/striped_dir/b
22097         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22098                 error "nlink error after rmdir"
22099
22100         chattr +i $DIR/$tdir/striped_dir
22101         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22102                 error "immutable flags not working under striped dir!"
22103         chattr -i $DIR/$tdir/striped_dir
22104
22105         rmdir $DIR/$tdir/striped_dir ||
22106                 error "rmdir striped dir error"
22107
22108         cleanup_test_300
22109
22110         true
22111 }
22112
22113 test_300a() {
22114         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22115                 skip "skipped for lustre < 2.7.0"
22116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22118
22119         test_striped_dir 0 || error "failed on striped dir on MDT0"
22120         test_striped_dir 1 || error "failed on striped dir on MDT0"
22121 }
22122 run_test 300a "basic striped dir sanity test"
22123
22124 test_300b() {
22125         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22126                 skip "skipped for lustre < 2.7.0"
22127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22128         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22129
22130         local i
22131         local mtime1
22132         local mtime2
22133         local mtime3
22134
22135         test_mkdir $DIR/$tdir || error "mkdir fail"
22136         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22137                 error "set striped dir error"
22138         for i in {0..9}; do
22139                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22140                 sleep 1
22141                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22142                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22143                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22144                 sleep 1
22145                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22146                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22147                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22148         done
22149         true
22150 }
22151 run_test 300b "check ctime/mtime for striped dir"
22152
22153 test_300c() {
22154         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22155                 skip "skipped for lustre < 2.7.0"
22156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22158
22159         local file_count
22160
22161         mkdir -p $DIR/$tdir
22162         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22163                 error "set striped dir error"
22164
22165         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22166                 error "chown striped dir failed"
22167
22168         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22169                 error "create 5k files failed"
22170
22171         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22172
22173         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22174
22175         rm -rf $DIR/$tdir
22176 }
22177 run_test 300c "chown && check ls under striped directory"
22178
22179 test_300d() {
22180         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22181                 skip "skipped for lustre < 2.7.0"
22182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22184
22185         local stripe_count
22186         local file
22187
22188         mkdir -p $DIR/$tdir
22189         $LFS setstripe -c 2 $DIR/$tdir
22190
22191         #local striped directory
22192         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22193                 error "set striped dir error"
22194         #look at the directories for debug purposes
22195         ls -l $DIR/$tdir
22196         $LFS getdirstripe $DIR/$tdir
22197         ls -l $DIR/$tdir/striped_dir
22198         $LFS getdirstripe $DIR/$tdir/striped_dir
22199         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22200                 error "create 10 files failed"
22201
22202         #remote striped directory
22203         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22204                 error "set striped dir error"
22205         #look at the directories for debug purposes
22206         ls -l $DIR/$tdir
22207         $LFS getdirstripe $DIR/$tdir
22208         ls -l $DIR/$tdir/remote_striped_dir
22209         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22210         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22211                 error "create 10 files failed"
22212
22213         for file in $(find $DIR/$tdir); do
22214                 stripe_count=$($LFS getstripe -c $file)
22215                 [ $stripe_count -eq 2 ] ||
22216                         error "wrong stripe $stripe_count for $file"
22217         done
22218
22219         rm -rf $DIR/$tdir
22220 }
22221 run_test 300d "check default stripe under striped directory"
22222
22223 test_300e() {
22224         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22225                 skip "Need MDS version at least 2.7.55"
22226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22228
22229         local stripe_count
22230         local file
22231
22232         mkdir -p $DIR/$tdir
22233
22234         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22235                 error "set striped dir error"
22236
22237         touch $DIR/$tdir/striped_dir/a
22238         touch $DIR/$tdir/striped_dir/b
22239         touch $DIR/$tdir/striped_dir/c
22240
22241         mkdir $DIR/$tdir/striped_dir/dir_a
22242         mkdir $DIR/$tdir/striped_dir/dir_b
22243         mkdir $DIR/$tdir/striped_dir/dir_c
22244
22245         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22246                 error "set striped adir under striped dir error"
22247
22248         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22249                 error "set striped bdir under striped dir error"
22250
22251         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22252                 error "set striped cdir under striped dir error"
22253
22254         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22255                 error "rename dir under striped dir fails"
22256
22257         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22258                 error "rename dir under different stripes fails"
22259
22260         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22261                 error "rename file under striped dir should succeed"
22262
22263         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22264                 error "rename dir under striped dir should succeed"
22265
22266         rm -rf $DIR/$tdir
22267 }
22268 run_test 300e "check rename under striped directory"
22269
22270 test_300f() {
22271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22273         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22274                 skip "Need MDS version at least 2.7.55"
22275
22276         local stripe_count
22277         local file
22278
22279         rm -rf $DIR/$tdir
22280         mkdir -p $DIR/$tdir
22281
22282         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22283                 error "set striped dir error"
22284
22285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22286                 error "set striped dir error"
22287
22288         touch $DIR/$tdir/striped_dir/a
22289         mkdir $DIR/$tdir/striped_dir/dir_a
22290         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22291                 error "create striped dir under striped dir fails"
22292
22293         touch $DIR/$tdir/striped_dir1/b
22294         mkdir $DIR/$tdir/striped_dir1/dir_b
22295         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22296                 error "create striped dir under striped dir fails"
22297
22298         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22299                 error "rename dir under different striped dir should fail"
22300
22301         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22302                 error "rename striped dir under diff striped dir should fail"
22303
22304         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22305                 error "rename file under diff striped dirs fails"
22306
22307         rm -rf $DIR/$tdir
22308 }
22309 run_test 300f "check rename cross striped directory"
22310
22311 test_300_check_default_striped_dir()
22312 {
22313         local dirname=$1
22314         local default_count=$2
22315         local default_index=$3
22316         local stripe_count
22317         local stripe_index
22318         local dir_stripe_index
22319         local dir
22320
22321         echo "checking $dirname $default_count $default_index"
22322         $LFS setdirstripe -D -c $default_count -i $default_index \
22323                                 -H all_char $DIR/$tdir/$dirname ||
22324                 error "set default stripe on striped dir error"
22325         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22326         [ $stripe_count -eq $default_count ] ||
22327                 error "expect $default_count get $stripe_count for $dirname"
22328
22329         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22330         [ $stripe_index -eq $default_index ] ||
22331                 error "expect $default_index get $stripe_index for $dirname"
22332
22333         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22334                                                 error "create dirs failed"
22335
22336         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22337         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22338         for dir in $(find $DIR/$tdir/$dirname/*); do
22339                 stripe_count=$($LFS getdirstripe -c $dir)
22340                 (( $stripe_count == $default_count )) ||
22341                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22342                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22343                 error "stripe count $default_count != $stripe_count for $dir"
22344
22345                 stripe_index=$($LFS getdirstripe -i $dir)
22346                 [ $default_index -eq -1 ] ||
22347                         [ $stripe_index -eq $default_index ] ||
22348                         error "$stripe_index != $default_index for $dir"
22349
22350                 #check default stripe
22351                 stripe_count=$($LFS getdirstripe -D -c $dir)
22352                 [ $stripe_count -eq $default_count ] ||
22353                 error "default count $default_count != $stripe_count for $dir"
22354
22355                 stripe_index=$($LFS getdirstripe -D -i $dir)
22356                 [ $stripe_index -eq $default_index ] ||
22357                 error "default index $default_index != $stripe_index for $dir"
22358         done
22359         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22360 }
22361
22362 test_300g() {
22363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22364         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22365                 skip "Need MDS version at least 2.7.55"
22366
22367         local dir
22368         local stripe_count
22369         local stripe_index
22370
22371         mkdir $DIR/$tdir
22372         mkdir $DIR/$tdir/normal_dir
22373
22374         #Checking when client cache stripe index
22375         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22376         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22377                 error "create striped_dir failed"
22378
22379         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22380                 error "create dir0 fails"
22381         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22382         [ $stripe_index -eq 0 ] ||
22383                 error "dir0 expect index 0 got $stripe_index"
22384
22385         mkdir $DIR/$tdir/striped_dir/dir1 ||
22386                 error "create dir1 fails"
22387         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22388         [ $stripe_index -eq 1 ] ||
22389                 error "dir1 expect index 1 got $stripe_index"
22390
22391         #check default stripe count/stripe index
22392         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22393         test_300_check_default_striped_dir normal_dir 1 0
22394         test_300_check_default_striped_dir normal_dir -1 1
22395         test_300_check_default_striped_dir normal_dir 2 -1
22396
22397         #delete default stripe information
22398         echo "delete default stripeEA"
22399         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22400                 error "set default stripe on striped dir error"
22401
22402         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22403         for dir in $(find $DIR/$tdir/normal_dir/*); do
22404                 stripe_count=$($LFS getdirstripe -c $dir)
22405                 [ $stripe_count -eq 0 ] ||
22406                         error "expect 1 get $stripe_count for $dir"
22407                 stripe_index=$($LFS getdirstripe -i $dir)
22408                 [ $stripe_index -eq 0 ] ||
22409                         error "expect 0 get $stripe_index for $dir"
22410         done
22411 }
22412 run_test 300g "check default striped directory for normal directory"
22413
22414 test_300h() {
22415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22417                 skip "Need MDS version at least 2.7.55"
22418
22419         local dir
22420         local stripe_count
22421
22422         mkdir $DIR/$tdir
22423         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22424                 error "set striped dir error"
22425
22426         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22427         test_300_check_default_striped_dir striped_dir 1 0
22428         test_300_check_default_striped_dir striped_dir -1 1
22429         test_300_check_default_striped_dir striped_dir 2 -1
22430
22431         #delete default stripe information
22432         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22433                 error "set default stripe on striped dir error"
22434
22435         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22436         for dir in $(find $DIR/$tdir/striped_dir/*); do
22437                 stripe_count=$($LFS getdirstripe -c $dir)
22438                 [ $stripe_count -eq 0 ] ||
22439                         error "expect 1 get $stripe_count for $dir"
22440         done
22441 }
22442 run_test 300h "check default striped directory for striped directory"
22443
22444 test_300i() {
22445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22446         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22447         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22448                 skip "Need MDS version at least 2.7.55"
22449
22450         local stripe_count
22451         local file
22452
22453         mkdir $DIR/$tdir
22454
22455         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22456                 error "set striped dir error"
22457
22458         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22459                 error "create files under striped dir failed"
22460
22461         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22462                 error "set striped hashdir error"
22463
22464         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22465                 error "create dir0 under hash dir failed"
22466         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22467                 error "create dir1 under hash dir failed"
22468         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22469                 error "create dir2 under hash dir failed"
22470
22471         # unfortunately, we need to umount to clear dir layout cache for now
22472         # once we fully implement dir layout, we can drop this
22473         umount_client $MOUNT || error "umount failed"
22474         mount_client $MOUNT || error "mount failed"
22475
22476         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22477         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22478         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22479
22480         #set the stripe to be unknown hash type
22481         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22482         $LCTL set_param fail_loc=0x1901
22483         for ((i = 0; i < 10; i++)); do
22484                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22485                         error "stat f-$i failed"
22486                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22487         done
22488
22489         touch $DIR/$tdir/striped_dir/f0 &&
22490                 error "create under striped dir with unknown hash should fail"
22491
22492         $LCTL set_param fail_loc=0
22493
22494         umount_client $MOUNT || error "umount failed"
22495         mount_client $MOUNT || error "mount failed"
22496
22497         return 0
22498 }
22499 run_test 300i "client handle unknown hash type striped directory"
22500
22501 test_300j() {
22502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22504         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22505                 skip "Need MDS version at least 2.7.55"
22506
22507         local stripe_count
22508         local file
22509
22510         mkdir $DIR/$tdir
22511
22512         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22513         $LCTL set_param fail_loc=0x1702
22514         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22515                 error "set striped dir error"
22516
22517         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22518                 error "create files under striped dir failed"
22519
22520         $LCTL set_param fail_loc=0
22521
22522         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22523
22524         return 0
22525 }
22526 run_test 300j "test large update record"
22527
22528 test_300k() {
22529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22531         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22532                 skip "Need MDS version at least 2.7.55"
22533
22534         # this test needs a huge transaction
22535         local kb
22536         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22537              osd*.$FSNAME-MDT0000.kbytestotal")
22538         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22539
22540         local stripe_count
22541         local file
22542
22543         mkdir $DIR/$tdir
22544
22545         #define OBD_FAIL_LARGE_STRIPE   0x1703
22546         $LCTL set_param fail_loc=0x1703
22547         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22548                 error "set striped dir error"
22549         $LCTL set_param fail_loc=0
22550
22551         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22552                 error "getstripeddir fails"
22553         rm -rf $DIR/$tdir/striped_dir ||
22554                 error "unlink striped dir fails"
22555
22556         return 0
22557 }
22558 run_test 300k "test large striped directory"
22559
22560 test_300l() {
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 stripe_index
22567
22568         test_mkdir -p $DIR/$tdir/striped_dir
22569         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22570                         error "chown $RUNAS_ID failed"
22571         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22572                 error "set default striped dir failed"
22573
22574         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22575         $LCTL set_param fail_loc=0x80000158
22576         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22577
22578         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22579         [ $stripe_index -eq 1 ] ||
22580                 error "expect 1 get $stripe_index for $dir"
22581 }
22582 run_test 300l "non-root user to create dir under striped dir with stale layout"
22583
22584 test_300m() {
22585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22586         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22587         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22588                 skip "Need MDS version at least 2.7.55"
22589
22590         mkdir -p $DIR/$tdir/striped_dir
22591         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22592                 error "set default stripes dir error"
22593
22594         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22595
22596         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22597         [ $stripe_count -eq 0 ] ||
22598                         error "expect 0 get $stripe_count for a"
22599
22600         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22601                 error "set default stripes dir error"
22602
22603         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22604
22605         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22606         [ $stripe_count -eq 0 ] ||
22607                         error "expect 0 get $stripe_count for b"
22608
22609         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22610                 error "set default stripes dir error"
22611
22612         mkdir $DIR/$tdir/striped_dir/c &&
22613                 error "default stripe_index is invalid, mkdir c should fails"
22614
22615         rm -rf $DIR/$tdir || error "rmdir fails"
22616 }
22617 run_test 300m "setstriped directory on single MDT FS"
22618
22619 cleanup_300n() {
22620         local list=$(comma_list $(mdts_nodes))
22621
22622         trap 0
22623         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22624 }
22625
22626 test_300n() {
22627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22629         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22630                 skip "Need MDS version at least 2.7.55"
22631         remote_mds_nodsh && skip "remote MDS with nodsh"
22632
22633         local stripe_index
22634         local list=$(comma_list $(mdts_nodes))
22635
22636         trap cleanup_300n RETURN EXIT
22637         mkdir -p $DIR/$tdir
22638         chmod 777 $DIR/$tdir
22639         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22640                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22641                 error "create striped dir succeeds with gid=0"
22642
22643         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22644         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22645                 error "create striped dir fails with gid=-1"
22646
22647         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22648         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22649                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22650                 error "set default striped dir succeeds with gid=0"
22651
22652
22653         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22654         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22655                 error "set default striped dir fails with gid=-1"
22656
22657
22658         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22659         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22660                                         error "create test_dir fails"
22661         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22662                                         error "create test_dir1 fails"
22663         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22664                                         error "create test_dir2 fails"
22665         cleanup_300n
22666 }
22667 run_test 300n "non-root user to create dir under striped dir with default EA"
22668
22669 test_300o() {
22670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22672         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22673                 skip "Need MDS version at least 2.7.55"
22674
22675         local numfree1
22676         local numfree2
22677
22678         mkdir -p $DIR/$tdir
22679
22680         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22681         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22682         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22683                 skip "not enough free inodes $numfree1 $numfree2"
22684         fi
22685
22686         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22687         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22688         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22689                 skip "not enough free space $numfree1 $numfree2"
22690         fi
22691
22692         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22693                 error "setdirstripe fails"
22694
22695         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22696                 error "create dirs fails"
22697
22698         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22699         ls $DIR/$tdir/striped_dir > /dev/null ||
22700                 error "ls striped dir fails"
22701         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22702                 error "unlink big striped dir fails"
22703 }
22704 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22705
22706 test_300p() {
22707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22709         remote_mds_nodsh && skip "remote MDS with nodsh"
22710
22711         mkdir -p $DIR/$tdir
22712
22713         #define OBD_FAIL_OUT_ENOSPC     0x1704
22714         do_facet mds2 lctl set_param fail_loc=0x80001704
22715         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22716                  && error "create striped directory should fail"
22717
22718         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22719
22720         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22721         true
22722 }
22723 run_test 300p "create striped directory without space"
22724
22725 test_300q() {
22726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22727         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22728
22729         local fd=$(free_fd)
22730         local cmd="exec $fd<$tdir"
22731         cd $DIR
22732         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22733         eval $cmd
22734         cmd="exec $fd<&-"
22735         trap "eval $cmd" EXIT
22736         cd $tdir || error "cd $tdir fails"
22737         rmdir  ../$tdir || error "rmdir $tdir fails"
22738         mkdir local_dir && error "create dir succeeds"
22739         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22740         eval $cmd
22741         return 0
22742 }
22743 run_test 300q "create remote directory under orphan directory"
22744
22745 test_300r() {
22746         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22747                 skip "Need MDS version at least 2.7.55" && return
22748         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22749
22750         mkdir $DIR/$tdir
22751
22752         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22753                 error "set striped dir error"
22754
22755         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22756                 error "getstripeddir fails"
22757
22758         local stripe_count
22759         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22760                       awk '/lmv_stripe_count:/ { print $2 }')
22761
22762         [ $MDSCOUNT -ne $stripe_count ] &&
22763                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22764
22765         rm -rf $DIR/$tdir/striped_dir ||
22766                 error "unlink striped dir fails"
22767 }
22768 run_test 300r "test -1 striped directory"
22769
22770 test_300s_helper() {
22771         local count=$1
22772
22773         local stripe_dir=$DIR/$tdir/striped_dir.$count
22774
22775         $LFS mkdir -c $count $stripe_dir ||
22776                 error "lfs mkdir -c error"
22777
22778         $LFS getdirstripe $stripe_dir ||
22779                 error "lfs getdirstripe fails"
22780
22781         local stripe_count
22782         stripe_count=$($LFS getdirstripe $stripe_dir |
22783                       awk '/lmv_stripe_count:/ { print $2 }')
22784
22785         [ $count -ne $stripe_count ] &&
22786                 error_noexit "bad stripe count $stripe_count expected $count"
22787
22788         local dupe_stripes
22789         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22790                 awk '/0x/ {count[$1] += 1}; END {
22791                         for (idx in count) {
22792                                 if (count[idx]>1) {
22793                                         print "index " idx " count " count[idx]
22794                                 }
22795                         }
22796                 }')
22797
22798         if [[ -n "$dupe_stripes" ]] ; then
22799                 lfs getdirstripe $stripe_dir
22800                 error_noexit "Dupe MDT above: $dupe_stripes "
22801         fi
22802
22803         rm -rf $stripe_dir ||
22804                 error_noexit "unlink $stripe_dir fails"
22805 }
22806
22807 test_300s() {
22808         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22809                 skip "Need MDS version at least 2.7.55" && return
22810         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22811
22812         mkdir $DIR/$tdir
22813         for count in $(seq 2 $MDSCOUNT); do
22814                 test_300s_helper $count
22815         done
22816 }
22817 run_test 300s "test lfs mkdir -c without -i"
22818
22819
22820 prepare_remote_file() {
22821         mkdir $DIR/$tdir/src_dir ||
22822                 error "create remote source failed"
22823
22824         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22825                  error "cp to remote source failed"
22826         touch $DIR/$tdir/src_dir/a
22827
22828         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22829                 error "create remote target dir failed"
22830
22831         touch $DIR/$tdir/tgt_dir/b
22832
22833         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22834                 error "rename dir cross MDT failed!"
22835
22836         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22837                 error "src_child still exists after rename"
22838
22839         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22840                 error "missing file(a) after rename"
22841
22842         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22843                 error "diff after rename"
22844 }
22845
22846 test_310a() {
22847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22849
22850         local remote_file=$DIR/$tdir/tgt_dir/b
22851
22852         mkdir -p $DIR/$tdir
22853
22854         prepare_remote_file || error "prepare remote file failed"
22855
22856         #open-unlink file
22857         $OPENUNLINK $remote_file $remote_file ||
22858                 error "openunlink $remote_file failed"
22859         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22860 }
22861 run_test 310a "open unlink remote file"
22862
22863 test_310b() {
22864         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22866
22867         local remote_file=$DIR/$tdir/tgt_dir/b
22868
22869         mkdir -p $DIR/$tdir
22870
22871         prepare_remote_file || error "prepare remote file failed"
22872
22873         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22874         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22875         $CHECKSTAT -t file $remote_file || error "check file failed"
22876 }
22877 run_test 310b "unlink remote file with multiple links while open"
22878
22879 test_310c() {
22880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22881         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22882
22883         local remote_file=$DIR/$tdir/tgt_dir/b
22884
22885         mkdir -p $DIR/$tdir
22886
22887         prepare_remote_file || error "prepare remote file failed"
22888
22889         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22890         multiop_bg_pause $remote_file O_uc ||
22891                         error "mulitop failed for remote file"
22892         MULTIPID=$!
22893         $MULTIOP $DIR/$tfile Ouc
22894         kill -USR1 $MULTIPID
22895         wait $MULTIPID
22896 }
22897 run_test 310c "open-unlink remote file with multiple links"
22898
22899 #LU-4825
22900 test_311() {
22901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22902         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22903         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22904                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22905         remote_mds_nodsh && skip "remote MDS with nodsh"
22906
22907         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22908         local mdts=$(comma_list $(mdts_nodes))
22909
22910         mkdir -p $DIR/$tdir
22911         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22912         createmany -o $DIR/$tdir/$tfile. 1000
22913
22914         # statfs data is not real time, let's just calculate it
22915         old_iused=$((old_iused + 1000))
22916
22917         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22918                         osp.*OST0000*MDT0000.create_count")
22919         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22920                                 osp.*OST0000*MDT0000.max_create_count")
22921         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22922
22923         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22924         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22925         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22926
22927         unlinkmany $DIR/$tdir/$tfile. 1000
22928
22929         do_nodes $mdts "$LCTL set_param -n \
22930                         osp.*OST0000*.max_create_count=$max_count"
22931         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22932                 do_nodes $mdts "$LCTL set_param -n \
22933                                 osp.*OST0000*.create_count=$count"
22934         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22935                         grep "=0" && error "create_count is zero"
22936
22937         local new_iused
22938         for i in $(seq 120); do
22939                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22940                 # system may be too busy to destroy all objs in time, use
22941                 # a somewhat small value to not fail autotest
22942                 [ $((old_iused - new_iused)) -gt 400 ] && break
22943                 sleep 1
22944         done
22945
22946         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22947         [ $((old_iused - new_iused)) -gt 400 ] ||
22948                 error "objs not destroyed after unlink"
22949 }
22950 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22951
22952 zfs_oid_to_objid()
22953 {
22954         local ost=$1
22955         local objid=$2
22956
22957         local vdevdir=$(dirname $(facet_vdevice $ost))
22958         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22959         local zfs_zapid=$(do_facet $ost $cmd |
22960                           grep -w "/O/0/d$((objid%32))" -C 5 |
22961                           awk '/Object/{getline; print $1}')
22962         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22963                           awk "/$objid = /"'{printf $3}')
22964
22965         echo $zfs_objid
22966 }
22967
22968 zfs_object_blksz() {
22969         local ost=$1
22970         local objid=$2
22971
22972         local vdevdir=$(dirname $(facet_vdevice $ost))
22973         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22974         local blksz=$(do_facet $ost $cmd $objid |
22975                       awk '/dblk/{getline; printf $4}')
22976
22977         case "${blksz: -1}" in
22978                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22979                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22980                 *) ;;
22981         esac
22982
22983         echo $blksz
22984 }
22985
22986 test_312() { # LU-4856
22987         remote_ost_nodsh && skip "remote OST with nodsh"
22988         [ "$ost1_FSTYPE" = "zfs" ] ||
22989                 skip_env "the test only applies to zfs"
22990
22991         local max_blksz=$(do_facet ost1 \
22992                           $ZFS get -p recordsize $(facet_device ost1) |
22993                           awk '!/VALUE/{print $3}')
22994
22995         # to make life a little bit easier
22996         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22997         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22998
22999         local tf=$DIR/$tdir/$tfile
23000         touch $tf
23001         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23002
23003         # Get ZFS object id
23004         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23005         # block size change by sequential overwrite
23006         local bs
23007
23008         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23009                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23010
23011                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23012                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23013         done
23014         rm -f $tf
23015
23016         # block size change by sequential append write
23017         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23018         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23019         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23020         local count
23021
23022         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23023                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23024                         oflag=sync conv=notrunc
23025
23026                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23027                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23028                         error "blksz error, actual $blksz, " \
23029                                 "expected: 2 * $count * $PAGE_SIZE"
23030         done
23031         rm -f $tf
23032
23033         # random write
23034         touch $tf
23035         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23036         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23037
23038         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23039         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23040         [ $blksz -eq $PAGE_SIZE ] ||
23041                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23042
23043         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23044         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23045         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23046
23047         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23048         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23049         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23050 }
23051 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23052
23053 test_313() {
23054         remote_ost_nodsh && skip "remote OST with nodsh"
23055
23056         local file=$DIR/$tfile
23057
23058         rm -f $file
23059         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23060
23061         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23062         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23063         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23064                 error "write should failed"
23065         do_facet ost1 "$LCTL set_param fail_loc=0"
23066         rm -f $file
23067 }
23068 run_test 313 "io should fail after last_rcvd update fail"
23069
23070 test_314() {
23071         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23072
23073         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23074         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23075         rm -f $DIR/$tfile
23076         wait_delete_completed
23077         do_facet ost1 "$LCTL set_param fail_loc=0"
23078 }
23079 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23080
23081 test_315() { # LU-618
23082         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23083
23084         local file=$DIR/$tfile
23085         rm -f $file
23086
23087         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23088                 error "multiop file write failed"
23089         $MULTIOP $file oO_RDONLY:r4063232_c &
23090         PID=$!
23091
23092         sleep 2
23093
23094         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23095         kill -USR1 $PID
23096
23097         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23098         rm -f $file
23099 }
23100 run_test 315 "read should be accounted"
23101
23102 test_316() {
23103         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23104         large_xattr_enabled || skip_env "ea_inode feature disabled"
23105
23106         rm -rf $DIR/$tdir/d
23107         mkdir -p $DIR/$tdir/d
23108         chown nobody $DIR/$tdir/d
23109         touch $DIR/$tdir/d/file
23110
23111         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23112 }
23113 run_test 316 "lfs mv"
23114
23115 test_317() {
23116         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23117                 skip "Need MDS version at least 2.11.53"
23118         if [ "$ost1_FSTYPE" == "zfs" ]; then
23119                 skip "LU-10370: no implementation for ZFS"
23120         fi
23121
23122         local trunc_sz
23123         local grant_blk_size
23124
23125         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23126                         awk '/grant_block_size:/ { print $2; exit; }')
23127         #
23128         # Create File of size 5M. Truncate it to below size's and verify
23129         # blocks count.
23130         #
23131         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23132                 error "Create file $DIR/$tfile failed"
23133         stack_trap "rm -f $DIR/$tfile" EXIT
23134
23135         for trunc_sz in 2097152 4097 4000 509 0; do
23136                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23137                         error "truncate $tfile to $trunc_sz failed"
23138                 local sz=$(stat --format=%s $DIR/$tfile)
23139                 local blk=$(stat --format=%b $DIR/$tfile)
23140                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23141                                      grant_blk_size) * 8))
23142
23143                 if [[ $blk -ne $trunc_blk ]]; then
23144                         $(which stat) $DIR/$tfile
23145                         error "Expected Block $trunc_blk got $blk for $tfile"
23146                 fi
23147
23148                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23149                         error "Expected Size $trunc_sz got $sz for $tfile"
23150         done
23151
23152         #
23153         # sparse file test
23154         # Create file with a hole and write actual two blocks. Block count
23155         # must be 16.
23156         #
23157         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23158                 conv=fsync || error "Create file : $DIR/$tfile"
23159
23160         # Calculate the final truncate size.
23161         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23162
23163         #
23164         # truncate to size $trunc_sz bytes. Strip the last block
23165         # The block count must drop to 8
23166         #
23167         $TRUNCATE $DIR/$tfile $trunc_sz ||
23168                 error "truncate $tfile to $trunc_sz failed"
23169
23170         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23171         sz=$(stat --format=%s $DIR/$tfile)
23172         blk=$(stat --format=%b $DIR/$tfile)
23173
23174         if [[ $blk -ne $trunc_bsz ]]; then
23175                 $(which stat) $DIR/$tfile
23176                 error "Expected Block $trunc_bsz got $blk for $tfile"
23177         fi
23178
23179         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23180                 error "Expected Size $trunc_sz got $sz for $tfile"
23181 }
23182 run_test 317 "Verify blocks get correctly update after truncate"
23183
23184 test_318() {
23185         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23186         local old_max_active=$($LCTL get_param -n \
23187                             ${llite_name}.max_read_ahead_async_active \
23188                             2>/dev/null)
23189
23190         $LCTL set_param llite.*.max_read_ahead_async_active=256
23191         local max_active=$($LCTL get_param -n \
23192                            ${llite_name}.max_read_ahead_async_active \
23193                            2>/dev/null)
23194         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23195
23196         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23197                 error "set max_read_ahead_async_active should succeed"
23198
23199         $LCTL set_param llite.*.max_read_ahead_async_active=512
23200         max_active=$($LCTL get_param -n \
23201                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23202         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23203
23204         # restore @max_active
23205         [ $old_max_active -ne 0 ] && $LCTL set_param \
23206                 llite.*.max_read_ahead_async_active=$old_max_active
23207
23208         local old_threshold=$($LCTL get_param -n \
23209                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23210         local max_per_file_mb=$($LCTL get_param -n \
23211                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23212
23213         local invalid=$(($max_per_file_mb + 1))
23214         $LCTL set_param \
23215                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23216                         && error "set $invalid should fail"
23217
23218         local valid=$(($invalid - 1))
23219         $LCTL set_param \
23220                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23221                         error "set $valid should succeed"
23222         local threshold=$($LCTL get_param -n \
23223                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23224         [ $threshold -eq $valid ] || error \
23225                 "expect threshold $valid got $threshold"
23226         $LCTL set_param \
23227                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23228 }
23229 run_test 318 "Verify async readahead tunables"
23230
23231 test_319() {
23232         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23233
23234         local before=$(date +%s)
23235         local evict
23236         local mdir=$DIR/$tdir
23237         local file=$mdir/xxx
23238
23239         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23240         touch $file
23241
23242 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23243         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23244         $LFS mv -m1 $file &
23245
23246         sleep 1
23247         dd if=$file of=/dev/null
23248         wait
23249         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23250           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23251
23252         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23253 }
23254 run_test 319 "lost lease lock on migrate error"
23255
23256 test_398a() { # LU-4198
23257         local ost1_imp=$(get_osc_import_name client ost1)
23258         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23259                          cut -d'.' -f2)
23260
23261         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23262         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23263
23264         # request a new lock on client
23265         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23266
23267         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23268         local lock_count=$($LCTL get_param -n \
23269                            ldlm.namespaces.$imp_name.lru_size)
23270         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23271
23272         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23273
23274         # no lock cached, should use lockless IO and not enqueue new lock
23275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23276         lock_count=$($LCTL get_param -n \
23277                      ldlm.namespaces.$imp_name.lru_size)
23278         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23279 }
23280 run_test 398a "direct IO should cancel lock otherwise lockless"
23281
23282 test_398b() { # LU-4198
23283         which fio || skip_env "no fio installed"
23284         $LFS setstripe -c -1 $DIR/$tfile
23285
23286         local size=12
23287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23288
23289         local njobs=4
23290         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23291         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23292                 --numjobs=$njobs --fallocate=none \
23293                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23294                 --filename=$DIR/$tfile &
23295         bg_pid=$!
23296
23297         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23298         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23299                 --numjobs=$njobs --fallocate=none \
23300                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23301                 --filename=$DIR/$tfile || true
23302         wait $bg_pid
23303
23304         rm -f $DIR/$tfile
23305 }
23306 run_test 398b "DIO and buffer IO race"
23307
23308 test_398c() { # LU-4198
23309         local ost1_imp=$(get_osc_import_name client ost1)
23310         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23311                          cut -d'.' -f2)
23312
23313         which fio || skip_env "no fio installed"
23314
23315         saved_debug=$($LCTL get_param -n debug)
23316         $LCTL set_param debug=0
23317
23318         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23319         ((size /= 1024)) # by megabytes
23320         ((size /= 2)) # write half of the OST at most
23321         [ $size -gt 40 ] && size=40 #reduce test time anyway
23322
23323         $LFS setstripe -c 1 $DIR/$tfile
23324
23325         # it seems like ldiskfs reserves more space than necessary if the
23326         # writing blocks are not mapped, so it extends the file firstly
23327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23328         cancel_lru_locks osc
23329
23330         # clear and verify rpc_stats later
23331         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23332
23333         local njobs=4
23334         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23335         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23336                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23337                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23338                 --filename=$DIR/$tfile
23339         [ $? -eq 0 ] || error "fio write error"
23340
23341         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23342                 error "Locks were requested while doing AIO"
23343
23344         # get the percentage of 1-page I/O
23345         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23346                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23347                 awk '{print $7}')
23348         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23349
23350         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23351         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23352                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23353                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23354                 --filename=$DIR/$tfile
23355         [ $? -eq 0 ] || error "fio mixed read write error"
23356
23357         echo "AIO with large block size ${size}M"
23358         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23359                 --numjobs=1 --fallocate=none --ioengine=libaio \
23360                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23361                 --filename=$DIR/$tfile
23362         [ $? -eq 0 ] || error "fio large block size failed"
23363
23364         rm -f $DIR/$tfile
23365         $LCTL set_param debug="$saved_debug"
23366 }
23367 run_test 398c "run fio to test AIO"
23368
23369 test_398d() { #  LU-13846
23370         which aiocp || skip_env "no aiocp installed"
23371         local aio_file=$DIR/$tfile.aio
23372
23373         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23374
23375         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23376         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23377         stack_trap "rm -f $DIR/$tfile $aio_file"
23378
23379         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23380
23381         # make sure we don't crash and fail properly
23382         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23383                 error "aio not aligned with PAGE SIZE should fail"
23384
23385         rm -f $DIR/$tfile $aio_file
23386 }
23387 run_test 398d "run aiocp to verify block size > stripe size"
23388
23389 test_398e() {
23390         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23391         touch $DIR/$tfile.new
23392         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23393 }
23394 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23395
23396 test_398f() { #  LU-14687
23397         which aiocp || skip_env "no aiocp installed"
23398         local aio_file=$DIR/$tfile.aio
23399
23400         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23401
23402         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23403         stack_trap "rm -f $DIR/$tfile $aio_file"
23404
23405         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23406         $LCTL set_param fail_loc=0x1418
23407         # make sure we don't crash and fail properly
23408         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23409                 error "aio with page allocation failure succeeded"
23410         $LCTL set_param fail_loc=0
23411         diff $DIR/$tfile $aio_file
23412         [[ $? != 0 ]] || error "no diff after failed aiocp"
23413 }
23414 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23415
23416 test_fake_rw() {
23417         local read_write=$1
23418         if [ "$read_write" = "write" ]; then
23419                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23420         elif [ "$read_write" = "read" ]; then
23421                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23422         else
23423                 error "argument error"
23424         fi
23425
23426         # turn off debug for performance testing
23427         local saved_debug=$($LCTL get_param -n debug)
23428         $LCTL set_param debug=0
23429
23430         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23431
23432         # get ost1 size - $FSNAME-OST0000
23433         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23434         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23435         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23436
23437         if [ "$read_write" = "read" ]; then
23438                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23439         fi
23440
23441         local start_time=$(date +%s.%N)
23442         $dd_cmd bs=1M count=$blocks oflag=sync ||
23443                 error "real dd $read_write error"
23444         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23445
23446         if [ "$read_write" = "write" ]; then
23447                 rm -f $DIR/$tfile
23448         fi
23449
23450         # define OBD_FAIL_OST_FAKE_RW           0x238
23451         do_facet ost1 $LCTL set_param fail_loc=0x238
23452
23453         local start_time=$(date +%s.%N)
23454         $dd_cmd bs=1M count=$blocks oflag=sync ||
23455                 error "fake dd $read_write error"
23456         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23457
23458         if [ "$read_write" = "write" ]; then
23459                 # verify file size
23460                 cancel_lru_locks osc
23461                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23462                         error "$tfile size not $blocks MB"
23463         fi
23464         do_facet ost1 $LCTL set_param fail_loc=0
23465
23466         echo "fake $read_write $duration_fake vs. normal $read_write" \
23467                 "$duration in seconds"
23468         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23469                 error_not_in_vm "fake write is slower"
23470
23471         $LCTL set_param -n debug="$saved_debug"
23472         rm -f $DIR/$tfile
23473 }
23474 test_399a() { # LU-7655 for OST fake write
23475         remote_ost_nodsh && skip "remote OST with nodsh"
23476
23477         test_fake_rw write
23478 }
23479 run_test 399a "fake write should not be slower than normal write"
23480
23481 test_399b() { # LU-8726 for OST fake read
23482         remote_ost_nodsh && skip "remote OST with nodsh"
23483         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23484                 skip_env "ldiskfs only test"
23485         fi
23486
23487         test_fake_rw read
23488 }
23489 run_test 399b "fake read should not be slower than normal read"
23490
23491 test_400a() { # LU-1606, was conf-sanity test_74
23492         if ! which $CC > /dev/null 2>&1; then
23493                 skip_env "$CC is not installed"
23494         fi
23495
23496         local extra_flags=''
23497         local out=$TMP/$tfile
23498         local prefix=/usr/include/lustre
23499         local prog
23500
23501         # Oleg removes c files in his test rig so test if any c files exist
23502         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23503                 skip_env "Needed c test files are missing"
23504
23505         if ! [[ -d $prefix ]]; then
23506                 # Assume we're running in tree and fixup the include path.
23507                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23508                 extra_flags+=" -L$LUSTRE/utils/.lib"
23509         fi
23510
23511         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23512                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23513                         error "client api broken"
23514         done
23515         rm -f $out
23516 }
23517 run_test 400a "Lustre client api program can compile and link"
23518
23519 test_400b() { # LU-1606, LU-5011
23520         local header
23521         local out=$TMP/$tfile
23522         local prefix=/usr/include/linux/lustre
23523
23524         # We use a hard coded prefix so that this test will not fail
23525         # when run in tree. There are headers in lustre/include/lustre/
23526         # that are not packaged (like lustre_idl.h) and have more
23527         # complicated include dependencies (like config.h and lnet/types.h).
23528         # Since this test about correct packaging we just skip them when
23529         # they don't exist (see below) rather than try to fixup cppflags.
23530
23531         if ! which $CC > /dev/null 2>&1; then
23532                 skip_env "$CC is not installed"
23533         fi
23534
23535         for header in $prefix/*.h; do
23536                 if ! [[ -f "$header" ]]; then
23537                         continue
23538                 fi
23539
23540                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23541                         continue # lustre_ioctl.h is internal header
23542                 fi
23543
23544                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23545                         error "cannot compile '$header'"
23546         done
23547         rm -f $out
23548 }
23549 run_test 400b "packaged headers can be compiled"
23550
23551 test_401a() { #LU-7437
23552         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23553         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23554
23555         #count the number of parameters by "list_param -R"
23556         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23557         #count the number of parameters by listing proc files
23558         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23559         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23560         echo "proc_dirs='$proc_dirs'"
23561         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23562         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23563                       sort -u | wc -l)
23564
23565         [ $params -eq $procs ] ||
23566                 error "found $params parameters vs. $procs proc files"
23567
23568         # test the list_param -D option only returns directories
23569         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23570         #count the number of parameters by listing proc directories
23571         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23572                 sort -u | wc -l)
23573
23574         [ $params -eq $procs ] ||
23575                 error "found $params parameters vs. $procs proc files"
23576 }
23577 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23578
23579 test_401b() {
23580         # jobid_var may not allow arbitrary values, so use jobid_name
23581         # if available
23582         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23583                 local testname=jobid_name tmp='testing%p'
23584         else
23585                 local testname=jobid_var tmp=testing
23586         fi
23587
23588         local save=$($LCTL get_param -n $testname)
23589
23590         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23591                 error "no error returned when setting bad parameters"
23592
23593         local jobid_new=$($LCTL get_param -n foe $testname baz)
23594         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23595
23596         $LCTL set_param -n fog=bam $testname=$save bat=fog
23597         local jobid_old=$($LCTL get_param -n foe $testname bag)
23598         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23599 }
23600 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23601
23602 test_401c() {
23603         # jobid_var may not allow arbitrary values, so use jobid_name
23604         # if available
23605         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23606                 local testname=jobid_name
23607         else
23608                 local testname=jobid_var
23609         fi
23610
23611         local jobid_var_old=$($LCTL get_param -n $testname)
23612         local jobid_var_new
23613
23614         $LCTL set_param $testname= &&
23615                 error "no error returned for 'set_param a='"
23616
23617         jobid_var_new=$($LCTL get_param -n $testname)
23618         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23619                 error "$testname was changed by setting without value"
23620
23621         $LCTL set_param $testname &&
23622                 error "no error returned for 'set_param a'"
23623
23624         jobid_var_new=$($LCTL get_param -n $testname)
23625         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23626                 error "$testname was changed by setting without value"
23627 }
23628 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23629
23630 test_401d() {
23631         # jobid_var may not allow arbitrary values, so use jobid_name
23632         # if available
23633         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23634                 local testname=jobid_name new_value='foo=bar%p'
23635         else
23636                 local testname=jobid_var new_valuie=foo=bar
23637         fi
23638
23639         local jobid_var_old=$($LCTL get_param -n $testname)
23640         local jobid_var_new
23641
23642         $LCTL set_param $testname=$new_value ||
23643                 error "'set_param a=b' did not accept a value containing '='"
23644
23645         jobid_var_new=$($LCTL get_param -n $testname)
23646         [[ "$jobid_var_new" == "$new_value" ]] ||
23647                 error "'set_param a=b' failed on a value containing '='"
23648
23649         # Reset the $testname to test the other format
23650         $LCTL set_param $testname=$jobid_var_old
23651         jobid_var_new=$($LCTL get_param -n $testname)
23652         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23653                 error "failed to reset $testname"
23654
23655         $LCTL set_param $testname $new_value ||
23656                 error "'set_param a b' did not accept a value containing '='"
23657
23658         jobid_var_new=$($LCTL get_param -n $testname)
23659         [[ "$jobid_var_new" == "$new_value" ]] ||
23660                 error "'set_param a b' failed on a value containing '='"
23661
23662         $LCTL set_param $testname $jobid_var_old
23663         jobid_var_new=$($LCTL get_param -n $testname)
23664         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23665                 error "failed to reset $testname"
23666 }
23667 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23668
23669 test_402() {
23670         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23671         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23672                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23673         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23674                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23675                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23676         remote_mds_nodsh && skip "remote MDS with nodsh"
23677
23678         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23679 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23680         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23681         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23682                 echo "Touch failed - OK"
23683 }
23684 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23685
23686 test_403() {
23687         local file1=$DIR/$tfile.1
23688         local file2=$DIR/$tfile.2
23689         local tfile=$TMP/$tfile
23690
23691         rm -f $file1 $file2 $tfile
23692
23693         touch $file1
23694         ln $file1 $file2
23695
23696         # 30 sec OBD_TIMEOUT in ll_getattr()
23697         # right before populating st_nlink
23698         $LCTL set_param fail_loc=0x80001409
23699         stat -c %h $file1 > $tfile &
23700
23701         # create an alias, drop all locks and reclaim the dentry
23702         < $file2
23703         cancel_lru_locks mdc
23704         cancel_lru_locks osc
23705         sysctl -w vm.drop_caches=2
23706
23707         wait
23708
23709         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23710
23711         rm -f $tfile $file1 $file2
23712 }
23713 run_test 403 "i_nlink should not drop to zero due to aliasing"
23714
23715 test_404() { # LU-6601
23716         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23717                 skip "Need server version newer than 2.8.52"
23718         remote_mds_nodsh && skip "remote MDS with nodsh"
23719
23720         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23721                 awk '/osp .*-osc-MDT/ { print $4}')
23722
23723         local osp
23724         for osp in $mosps; do
23725                 echo "Deactivate: " $osp
23726                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23727                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23728                         awk -vp=$osp '$4 == p { print $2 }')
23729                 [ $stat = IN ] || {
23730                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23731                         error "deactivate error"
23732                 }
23733                 echo "Activate: " $osp
23734                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23735                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23736                         awk -vp=$osp '$4 == p { print $2 }')
23737                 [ $stat = UP ] || {
23738                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23739                         error "activate error"
23740                 }
23741         done
23742 }
23743 run_test 404 "validate manual {de}activated works properly for OSPs"
23744
23745 test_405() {
23746         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23747         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23748                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23749                         skip "Layout swap lock is not supported"
23750
23751         check_swap_layouts_support
23752         check_swap_layout_no_dom $DIR
23753
23754         test_mkdir $DIR/$tdir
23755         swap_lock_test -d $DIR/$tdir ||
23756                 error "One layout swap locked test failed"
23757 }
23758 run_test 405 "Various layout swap lock tests"
23759
23760 test_406() {
23761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23762         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23765         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23766                 skip "Need MDS version at least 2.8.50"
23767
23768         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23769         local test_pool=$TESTNAME
23770
23771         pool_add $test_pool || error "pool_add failed"
23772         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23773                 error "pool_add_targets failed"
23774
23775         save_layout_restore_at_exit $MOUNT
23776
23777         # parent set default stripe count only, child will stripe from both
23778         # parent and fs default
23779         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23780                 error "setstripe $MOUNT failed"
23781         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23782         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23783         for i in $(seq 10); do
23784                 local f=$DIR/$tdir/$tfile.$i
23785                 touch $f || error "touch failed"
23786                 local count=$($LFS getstripe -c $f)
23787                 [ $count -eq $OSTCOUNT ] ||
23788                         error "$f stripe count $count != $OSTCOUNT"
23789                 local offset=$($LFS getstripe -i $f)
23790                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23791                 local size=$($LFS getstripe -S $f)
23792                 [ $size -eq $((def_stripe_size * 2)) ] ||
23793                         error "$f stripe size $size != $((def_stripe_size * 2))"
23794                 local pool=$($LFS getstripe -p $f)
23795                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23796         done
23797
23798         # change fs default striping, delete parent default striping, now child
23799         # will stripe from new fs default striping only
23800         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23801                 error "change $MOUNT default stripe failed"
23802         $LFS setstripe -c 0 $DIR/$tdir ||
23803                 error "delete $tdir default stripe failed"
23804         for i in $(seq 11 20); do
23805                 local f=$DIR/$tdir/$tfile.$i
23806                 touch $f || error "touch $f failed"
23807                 local count=$($LFS getstripe -c $f)
23808                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23809                 local offset=$($LFS getstripe -i $f)
23810                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23811                 local size=$($LFS getstripe -S $f)
23812                 [ $size -eq $def_stripe_size ] ||
23813                         error "$f stripe size $size != $def_stripe_size"
23814                 local pool=$($LFS getstripe -p $f)
23815                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23816         done
23817
23818         unlinkmany $DIR/$tdir/$tfile. 1 20
23819
23820         local f=$DIR/$tdir/$tfile
23821         pool_remove_all_targets $test_pool $f
23822         pool_remove $test_pool $f
23823 }
23824 run_test 406 "DNE support fs default striping"
23825
23826 test_407() {
23827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23828         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23829                 skip "Need MDS version at least 2.8.55"
23830         remote_mds_nodsh && skip "remote MDS with nodsh"
23831
23832         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23833                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23834         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23835                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23836         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23837
23838         #define OBD_FAIL_DT_TXN_STOP    0x2019
23839         for idx in $(seq $MDSCOUNT); do
23840                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23841         done
23842         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23843         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23844                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23845         true
23846 }
23847 run_test 407 "transaction fail should cause operation fail"
23848
23849 test_408() {
23850         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23851
23852         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23853         lctl set_param fail_loc=0x8000040a
23854         # let ll_prepare_partial_page() fail
23855         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23856
23857         rm -f $DIR/$tfile
23858
23859         # create at least 100 unused inodes so that
23860         # shrink_icache_memory(0) should not return 0
23861         touch $DIR/$tfile-{0..100}
23862         rm -f $DIR/$tfile-{0..100}
23863         sync
23864
23865         echo 2 > /proc/sys/vm/drop_caches
23866 }
23867 run_test 408 "drop_caches should not hang due to page leaks"
23868
23869 test_409()
23870 {
23871         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23872
23873         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23874         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23875         touch $DIR/$tdir/guard || error "(2) Fail to create"
23876
23877         local PREFIX=$(str_repeat 'A' 128)
23878         echo "Create 1K hard links start at $(date)"
23879         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23880                 error "(3) Fail to hard link"
23881
23882         echo "Links count should be right although linkEA overflow"
23883         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23884         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23885         [ $linkcount -eq 1001 ] ||
23886                 error "(5) Unexpected hard links count: $linkcount"
23887
23888         echo "List all links start at $(date)"
23889         ls -l $DIR/$tdir/foo > /dev/null ||
23890                 error "(6) Fail to list $DIR/$tdir/foo"
23891
23892         echo "Unlink hard links start at $(date)"
23893         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23894                 error "(7) Fail to unlink"
23895         echo "Unlink hard links finished at $(date)"
23896 }
23897 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23898
23899 test_410()
23900 {
23901         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23902                 skip "Need client version at least 2.9.59"
23903         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23904                 skip "Need MODULES build"
23905
23906         # Create a file, and stat it from the kernel
23907         local testfile=$DIR/$tfile
23908         touch $testfile
23909
23910         local run_id=$RANDOM
23911         local my_ino=$(stat --format "%i" $testfile)
23912
23913         # Try to insert the module. This will always fail as the
23914         # module is designed to not be inserted.
23915         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23916             &> /dev/null
23917
23918         # Anything but success is a test failure
23919         dmesg | grep -q \
23920             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23921             error "no inode match"
23922 }
23923 run_test 410 "Test inode number returned from kernel thread"
23924
23925 cleanup_test411_cgroup() {
23926         trap 0
23927         rmdir "$1"
23928 }
23929
23930 test_411() {
23931         local cg_basedir=/sys/fs/cgroup/memory
23932         # LU-9966
23933         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23934                 skip "no setup for cgroup"
23935
23936         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23937                 error "test file creation failed"
23938         cancel_lru_locks osc
23939
23940         # Create a very small memory cgroup to force a slab allocation error
23941         local cgdir=$cg_basedir/osc_slab_alloc
23942         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23943         trap "cleanup_test411_cgroup $cgdir" EXIT
23944         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23945         echo 1M > $cgdir/memory.limit_in_bytes
23946
23947         # Should not LBUG, just be killed by oom-killer
23948         # dd will return 0 even allocation failure in some environment.
23949         # So don't check return value
23950         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23951         cleanup_test411_cgroup $cgdir
23952
23953         return 0
23954 }
23955 run_test 411 "Slab allocation error with cgroup does not LBUG"
23956
23957 test_412() {
23958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23959         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23960                 skip "Need server version at least 2.10.55"
23961         fi
23962
23963         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23964                 error "mkdir failed"
23965         $LFS getdirstripe $DIR/$tdir
23966         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23967         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23968                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23969         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23970         [ $stripe_count -eq 2 ] ||
23971                 error "expect 2 get $stripe_count"
23972 }
23973 run_test 412 "mkdir on specific MDTs"
23974
23975 test_qos_mkdir() {
23976         local mkdir_cmd=$1
23977         local stripe_count=$2
23978         local mdts=$(comma_list $(mdts_nodes))
23979
23980         local testdir
23981         local lmv_qos_prio_free
23982         local lmv_qos_threshold_rr
23983         local lmv_qos_maxage
23984         local lod_qos_prio_free
23985         local lod_qos_threshold_rr
23986         local lod_qos_maxage
23987         local count
23988         local i
23989
23990         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23991         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23992         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23993                 head -n1)
23994         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23995         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23996         stack_trap "$LCTL set_param \
23997                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23998         stack_trap "$LCTL set_param \
23999                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24000         stack_trap "$LCTL set_param \
24001                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24002
24003         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24004                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24005         lod_qos_prio_free=${lod_qos_prio_free%%%}
24006         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24007                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24008         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24009         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24010                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24011         stack_trap "do_nodes $mdts $LCTL set_param \
24012                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24013         stack_trap "do_nodes $mdts $LCTL set_param \
24014                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24015                 EXIT
24016         stack_trap "do_nodes $mdts $LCTL set_param \
24017                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24018
24019         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24020         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24021
24022         testdir=$DIR/$tdir-s$stripe_count/rr
24023
24024         local stripe_index=$($LFS getstripe -m $testdir)
24025         local test_mkdir_rr=true
24026
24027         getfattr -d -m dmv $testdir | grep dmv
24028         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24029                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24030
24031                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24032         fi
24033
24034         echo
24035         $test_mkdir_rr &&
24036                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24037                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24038
24039         for i in $(seq $((100 * MDSCOUNT))); do
24040                 eval $mkdir_cmd $testdir/subdir$i ||
24041                         error "$mkdir_cmd subdir$i failed"
24042         done
24043
24044         for i in $(seq $MDSCOUNT); do
24045                 count=$($LFS getdirstripe -i $testdir/* |
24046                                 grep ^$((i - 1))$ | wc -l)
24047                 echo "$count directories created on MDT$((i - 1))"
24048                 if $test_mkdir_rr; then
24049                         (( $count == 100 )) ||
24050                                 error "subdirs are not evenly distributed"
24051                 elif [ $((i - 1)) -eq $stripe_index ]; then
24052                         (( $count == 100 * MDSCOUNT )) ||
24053                                 error "$count subdirs created on MDT$((i - 1))"
24054                 else
24055                         (( $count == 0 )) ||
24056                                 error "$count subdirs created on MDT$((i - 1))"
24057                 fi
24058
24059                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24060                         count=$($LFS getdirstripe $testdir/* |
24061                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24062                         echo "$count stripes created on MDT$((i - 1))"
24063                         # deviation should < 5% of average
24064                         (( $count < 95 * stripe_count )) ||
24065                         (( $count > 105 * stripe_count)) &&
24066                                 error "stripes are not evenly distributed"
24067                 fi
24068         done
24069
24070         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24071         do_nodes $mdts $LCTL set_param \
24072                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24073
24074         echo
24075         echo "Check for uneven MDTs: "
24076
24077         local ffree
24078         local bavail
24079         local max
24080         local min
24081         local max_index
24082         local min_index
24083         local tmp
24084
24085         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24086         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24087         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24088
24089         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24090         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24091         max_index=0
24092         min_index=0
24093         for ((i = 1; i < ${#ffree[@]}; i++)); do
24094                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24095                 if [ $tmp -gt $max ]; then
24096                         max=$tmp
24097                         max_index=$i
24098                 fi
24099                 if [ $tmp -lt $min ]; then
24100                         min=$tmp
24101                         min_index=$i
24102                 fi
24103         done
24104
24105         (( ${ffree[min_index]} == 0 )) &&
24106                 skip "no free files in MDT$min_index"
24107         (( ${ffree[min_index]} > 100000000 )) &&
24108                 skip "too many free files in MDT$min_index"
24109
24110         # Check if we need to generate uneven MDTs
24111         local threshold=50
24112         local diff=$(((max - min) * 100 / min))
24113         local value="$(generate_string 1024)"
24114
24115         while [ $diff -lt $threshold ]; do
24116                 # generate uneven MDTs, create till $threshold% diff
24117                 echo -n "weight diff=$diff% must be > $threshold% ..."
24118                 count=$((${ffree[min_index]} / 10))
24119                 # 50 sec per 10000 files in vm
24120                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24121                         skip "$count files to create"
24122                 echo "Fill MDT$min_index with $count files"
24123                 [ -d $DIR/$tdir-MDT$min_index ] ||
24124                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24125                         error "mkdir $tdir-MDT$min_index failed"
24126                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24127                         error "create d$count failed"
24128
24129                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24130                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24131                 max=$(((${ffree[max_index]} >> 8) * \
24132                         (${bavail[max_index]} * bsize >> 16)))
24133                 min=$(((${ffree[min_index]} >> 8) * \
24134                         (${bavail[min_index]} * bsize >> 16)))
24135                 diff=$(((max - min) * 100 / min))
24136         done
24137
24138         echo "MDT filesfree available: ${ffree[@]}"
24139         echo "MDT blocks available: ${bavail[@]}"
24140         echo "weight diff=$diff%"
24141
24142         echo
24143         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24144
24145         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24146         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24147         # decrease statfs age, so that it can be updated in time
24148         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24149         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24150
24151         sleep 1
24152
24153         testdir=$DIR/$tdir-s$stripe_count/qos
24154
24155         for i in $(seq $((100 * MDSCOUNT))); do
24156                 eval $mkdir_cmd $testdir/subdir$i ||
24157                         error "$mkdir_cmd subdir$i failed"
24158         done
24159
24160         for i in $(seq $MDSCOUNT); do
24161                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24162                         wc -l)
24163                 echo "$count directories created on MDT$((i - 1))"
24164
24165                 if [ $stripe_count -gt 1 ]; then
24166                         count=$($LFS getdirstripe $testdir/* |
24167                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24168                         echo "$count stripes created on MDT$((i - 1))"
24169                 fi
24170         done
24171
24172         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24173         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24174
24175         # D-value should > 10% of averge
24176         (( $max - $min < 10 )) &&
24177                 error "subdirs shouldn't be evenly distributed"
24178
24179         # ditto
24180         if [ $stripe_count -gt 1 ]; then
24181                 max=$($LFS getdirstripe $testdir/* |
24182                         grep -P "^\s+$max_index\t" | wc -l)
24183                 min=$($LFS getdirstripe $testdir/* |
24184                         grep -P "^\s+$min_index\t" | wc -l)
24185                 (( $max - $min < 10 * $stripe_count )) &&
24186                         error "stripes shouldn't be evenly distributed"|| true
24187         fi
24188 }
24189
24190 test_413a() {
24191         [ $MDSCOUNT -lt 2 ] &&
24192                 skip "We need at least 2 MDTs for this test"
24193
24194         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24195                 skip "Need server version at least 2.12.52"
24196
24197         local stripe_count
24198
24199         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24200                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24201                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24202                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24203                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24204         done
24205 }
24206 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24207
24208 test_413b() {
24209         [ $MDSCOUNT -lt 2 ] &&
24210                 skip "We need at least 2 MDTs for this test"
24211
24212         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24213                 skip "Need server version at least 2.12.52"
24214
24215         local testdir
24216         local stripe_count
24217
24218         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24219                 testdir=$DIR/$tdir-s$stripe_count
24220                 mkdir $testdir || error "mkdir $testdir failed"
24221                 mkdir $testdir/rr || error "mkdir rr failed"
24222                 mkdir $testdir/qos || error "mkdir qos failed"
24223                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24224                         $testdir/rr || error "setdirstripe rr failed"
24225                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24226                         error "setdirstripe failed"
24227                 test_qos_mkdir "mkdir" $stripe_count
24228         done
24229 }
24230 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24231
24232 test_413c() {
24233         [ $MDSCOUNT -ge 2 ] ||
24234                 skip "We need at least 2 MDTs for this test"
24235
24236         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24237                 skip "Need server version at least 2.14.50"
24238
24239         local testdir
24240         local inherit
24241         local inherit_rr
24242
24243         testdir=$DIR/${tdir}-s1
24244         mkdir $testdir || error "mkdir $testdir failed"
24245         mkdir $testdir/rr || error "mkdir rr failed"
24246         mkdir $testdir/qos || error "mkdir qos failed"
24247         # default max_inherit is -1, default max_inherit_rr is 0
24248         $LFS setdirstripe -D -c 1 $testdir/rr ||
24249                 error "setdirstripe rr failed"
24250         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24251                 error "setdirstripe qos failed"
24252         test_qos_mkdir "mkdir" 1
24253
24254         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24255         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24256         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24257         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24258         (( $inherit_rr == 0 )) ||
24259                 error "rr/level1 inherit-rr $inherit_rr != 0"
24260
24261         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24262         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24263         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24264         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24265         (( $inherit_rr == 0 )) ||
24266                 error "qos/level1 inherit-rr $inherit_rr !=0"
24267         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24268         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24269                 error "level2 shouldn't have default LMV" || true
24270 }
24271 run_test 413c "mkdir with default LMV max inherit rr"
24272
24273 test_414() {
24274 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24275         $LCTL set_param fail_loc=0x80000521
24276         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24277         rm -f $DIR/$tfile
24278 }
24279 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24280
24281 test_415() {
24282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24283         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24284                 skip "Need server version at least 2.11.52"
24285
24286         # LU-11102
24287         local total
24288         local setattr_pid
24289         local start_time
24290         local end_time
24291         local duration
24292
24293         total=500
24294         # this test may be slow on ZFS
24295         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24296
24297         # though this test is designed for striped directory, let's test normal
24298         # directory too since lock is always saved as CoS lock.
24299         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24300         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24301
24302         (
24303                 while true; do
24304                         touch $DIR/$tdir
24305                 done
24306         ) &
24307         setattr_pid=$!
24308
24309         start_time=$(date +%s)
24310         for i in $(seq $total); do
24311                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24312                         > /dev/null
24313         done
24314         end_time=$(date +%s)
24315         duration=$((end_time - start_time))
24316
24317         kill -9 $setattr_pid
24318
24319         echo "rename $total files took $duration sec"
24320         [ $duration -lt 100 ] || error "rename took $duration sec"
24321 }
24322 run_test 415 "lock revoke is not missing"
24323
24324 test_416() {
24325         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24326                 skip "Need server version at least 2.11.55"
24327
24328         # define OBD_FAIL_OSD_TXN_START    0x19a
24329         do_facet mds1 lctl set_param fail_loc=0x19a
24330
24331         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24332
24333         true
24334 }
24335 run_test 416 "transaction start failure won't cause system hung"
24336
24337 cleanup_417() {
24338         trap 0
24339         do_nodes $(comma_list $(mdts_nodes)) \
24340                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24341         do_nodes $(comma_list $(mdts_nodes)) \
24342                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24343         do_nodes $(comma_list $(mdts_nodes)) \
24344                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24345 }
24346
24347 test_417() {
24348         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24349         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24350                 skip "Need MDS version at least 2.11.56"
24351
24352         trap cleanup_417 RETURN EXIT
24353
24354         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24355         do_nodes $(comma_list $(mdts_nodes)) \
24356                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24357         $LFS migrate -m 0 $DIR/$tdir.1 &&
24358                 error "migrate dir $tdir.1 should fail"
24359
24360         do_nodes $(comma_list $(mdts_nodes)) \
24361                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24362         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24363                 error "create remote dir $tdir.2 should fail"
24364
24365         do_nodes $(comma_list $(mdts_nodes)) \
24366                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24367         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24368                 error "create striped dir $tdir.3 should fail"
24369         true
24370 }
24371 run_test 417 "disable remote dir, striped dir and dir migration"
24372
24373 # Checks that the outputs of df [-i] and lfs df [-i] match
24374 #
24375 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24376 check_lfs_df() {
24377         local dir=$2
24378         local inodes
24379         local df_out
24380         local lfs_df_out
24381         local count
24382         local passed=false
24383
24384         # blocks or inodes
24385         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24386
24387         for count in {1..100}; do
24388                 cancel_lru_locks
24389                 sync; sleep 0.2
24390
24391                 # read the lines of interest
24392                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24393                         error "df $inodes $dir | tail -n +2 failed"
24394                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24395                         error "lfs df $inodes $dir | grep summary: failed"
24396
24397                 # skip first substrings of each output as they are different
24398                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24399                 # compare the two outputs
24400                 passed=true
24401                 for i in {1..5}; do
24402                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24403                 done
24404                 $passed && break
24405         done
24406
24407         if ! $passed; then
24408                 df -P $inodes $dir
24409                 echo
24410                 lfs df $inodes $dir
24411                 error "df and lfs df $1 output mismatch: "      \
24412                       "df ${inodes}: ${df_out[*]}, "            \
24413                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24414         fi
24415 }
24416
24417 test_418() {
24418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24419
24420         local dir=$DIR/$tdir
24421         local numfiles=$((RANDOM % 4096 + 2))
24422         local numblocks=$((RANDOM % 256 + 1))
24423
24424         wait_delete_completed
24425         test_mkdir $dir
24426
24427         # check block output
24428         check_lfs_df blocks $dir
24429         # check inode output
24430         check_lfs_df inodes $dir
24431
24432         # create a single file and retest
24433         echo "Creating a single file and testing"
24434         createmany -o $dir/$tfile- 1 &>/dev/null ||
24435                 error "creating 1 file in $dir failed"
24436         check_lfs_df blocks $dir
24437         check_lfs_df inodes $dir
24438
24439         # create a random number of files
24440         echo "Creating $((numfiles - 1)) files and testing"
24441         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24442                 error "creating $((numfiles - 1)) files in $dir failed"
24443
24444         # write a random number of blocks to the first test file
24445         echo "Writing $numblocks 4K blocks and testing"
24446         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24447                 count=$numblocks &>/dev/null ||
24448                 error "dd to $dir/${tfile}-0 failed"
24449
24450         # retest
24451         check_lfs_df blocks $dir
24452         check_lfs_df inodes $dir
24453
24454         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24455                 error "unlinking $numfiles files in $dir failed"
24456 }
24457 run_test 418 "df and lfs df outputs match"
24458
24459 test_419()
24460 {
24461         local dir=$DIR/$tdir
24462
24463         mkdir -p $dir
24464         touch $dir/file
24465
24466         cancel_lru_locks mdc
24467
24468         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24469         $LCTL set_param fail_loc=0x1410
24470         cat $dir/file
24471         $LCTL set_param fail_loc=0
24472         rm -rf $dir
24473 }
24474 run_test 419 "Verify open file by name doesn't crash kernel"
24475
24476 test_420()
24477 {
24478         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24479                 skip "Need MDS version at least 2.12.53"
24480
24481         local SAVE_UMASK=$(umask)
24482         local dir=$DIR/$tdir
24483         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24484
24485         mkdir -p $dir
24486         umask 0000
24487         mkdir -m03777 $dir/testdir
24488         ls -dn $dir/testdir
24489         # Need to remove trailing '.' when SELinux is enabled
24490         local dirperms=$(ls -dn $dir/testdir |
24491                          awk '{ sub(/\.$/, "", $1); print $1}')
24492         [ $dirperms == "drwxrwsrwt" ] ||
24493                 error "incorrect perms on $dir/testdir"
24494
24495         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24496                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24497         ls -n $dir/testdir/testfile
24498         local fileperms=$(ls -n $dir/testdir/testfile |
24499                           awk '{ sub(/\.$/, "", $1); print $1}')
24500         [ $fileperms == "-rwxr-xr-x" ] ||
24501                 error "incorrect perms on $dir/testdir/testfile"
24502
24503         umask $SAVE_UMASK
24504 }
24505 run_test 420 "clear SGID bit on non-directories for non-members"
24506
24507 test_421a() {
24508         local cnt
24509         local fid1
24510         local fid2
24511
24512         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24513                 skip "Need MDS version at least 2.12.54"
24514
24515         test_mkdir $DIR/$tdir
24516         createmany -o $DIR/$tdir/f 3
24517         cnt=$(ls -1 $DIR/$tdir | wc -l)
24518         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24519
24520         fid1=$(lfs path2fid $DIR/$tdir/f1)
24521         fid2=$(lfs path2fid $DIR/$tdir/f2)
24522         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24523
24524         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24525         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24526
24527         cnt=$(ls -1 $DIR/$tdir | wc -l)
24528         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24529
24530         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24531         createmany -o $DIR/$tdir/f 3
24532         cnt=$(ls -1 $DIR/$tdir | wc -l)
24533         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24534
24535         fid1=$(lfs path2fid $DIR/$tdir/f1)
24536         fid2=$(lfs path2fid $DIR/$tdir/f2)
24537         echo "remove using fsname $FSNAME"
24538         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24539
24540         cnt=$(ls -1 $DIR/$tdir | wc -l)
24541         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24542 }
24543 run_test 421a "simple rm by fid"
24544
24545 test_421b() {
24546         local cnt
24547         local FID1
24548         local FID2
24549
24550         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24551                 skip "Need MDS version at least 2.12.54"
24552
24553         test_mkdir $DIR/$tdir
24554         createmany -o $DIR/$tdir/f 3
24555         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24556         MULTIPID=$!
24557
24558         FID1=$(lfs path2fid $DIR/$tdir/f1)
24559         FID2=$(lfs path2fid $DIR/$tdir/f2)
24560         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24561
24562         kill -USR1 $MULTIPID
24563         wait
24564
24565         cnt=$(ls $DIR/$tdir | wc -l)
24566         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24567 }
24568 run_test 421b "rm by fid on open file"
24569
24570 test_421c() {
24571         local cnt
24572         local FIDS
24573
24574         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24575                 skip "Need MDS version at least 2.12.54"
24576
24577         test_mkdir $DIR/$tdir
24578         createmany -o $DIR/$tdir/f 3
24579         touch $DIR/$tdir/$tfile
24580         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24581         cnt=$(ls -1 $DIR/$tdir | wc -l)
24582         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24583
24584         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24585         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24586
24587         cnt=$(ls $DIR/$tdir | wc -l)
24588         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24589 }
24590 run_test 421c "rm by fid against hardlinked files"
24591
24592 test_421d() {
24593         local cnt
24594         local FIDS
24595
24596         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24597                 skip "Need MDS version at least 2.12.54"
24598
24599         test_mkdir $DIR/$tdir
24600         createmany -o $DIR/$tdir/f 4097
24601         cnt=$(ls -1 $DIR/$tdir | wc -l)
24602         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24603
24604         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24605         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24606
24607         cnt=$(ls $DIR/$tdir | wc -l)
24608         rm -rf $DIR/$tdir
24609         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24610 }
24611 run_test 421d "rmfid en masse"
24612
24613 test_421e() {
24614         local cnt
24615         local FID
24616
24617         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24618         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24619                 skip "Need MDS version at least 2.12.54"
24620
24621         mkdir -p $DIR/$tdir
24622         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24623         createmany -o $DIR/$tdir/striped_dir/f 512
24624         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24625         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24626
24627         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24628                 sed "s/[/][^:]*://g")
24629         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24630
24631         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24632         rm -rf $DIR/$tdir
24633         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24634 }
24635 run_test 421e "rmfid in DNE"
24636
24637 test_421f() {
24638         local cnt
24639         local FID
24640
24641         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24642                 skip "Need MDS version at least 2.12.54"
24643
24644         test_mkdir $DIR/$tdir
24645         touch $DIR/$tdir/f
24646         cnt=$(ls -1 $DIR/$tdir | wc -l)
24647         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24648
24649         FID=$(lfs path2fid $DIR/$tdir/f)
24650         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24651         # rmfid should fail
24652         cnt=$(ls -1 $DIR/$tdir | wc -l)
24653         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24654
24655         chmod a+rw $DIR/$tdir
24656         ls -la $DIR/$tdir
24657         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24658         # rmfid should fail
24659         cnt=$(ls -1 $DIR/$tdir | wc -l)
24660         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24661
24662         rm -f $DIR/$tdir/f
24663         $RUNAS touch $DIR/$tdir/f
24664         FID=$(lfs path2fid $DIR/$tdir/f)
24665         echo "rmfid as root"
24666         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24667         cnt=$(ls -1 $DIR/$tdir | wc -l)
24668         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24669
24670         rm -f $DIR/$tdir/f
24671         $RUNAS touch $DIR/$tdir/f
24672         cnt=$(ls -1 $DIR/$tdir | wc -l)
24673         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24674         FID=$(lfs path2fid $DIR/$tdir/f)
24675         # rmfid w/o user_fid2path mount option should fail
24676         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24677         cnt=$(ls -1 $DIR/$tdir | wc -l)
24678         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24679
24680         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24681         stack_trap "rmdir $tmpdir"
24682         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24683                 error "failed to mount client'"
24684         stack_trap "umount_client $tmpdir"
24685
24686         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24687         # rmfid should succeed
24688         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24689         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24690
24691         # rmfid shouldn't allow to remove files due to dir's permission
24692         chmod a+rwx $tmpdir/$tdir
24693         touch $tmpdir/$tdir/f
24694         ls -la $tmpdir/$tdir
24695         FID=$(lfs path2fid $tmpdir/$tdir/f)
24696         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24697         return 0
24698 }
24699 run_test 421f "rmfid checks permissions"
24700
24701 test_421g() {
24702         local cnt
24703         local FIDS
24704
24705         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24706         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24707                 skip "Need MDS version at least 2.12.54"
24708
24709         mkdir -p $DIR/$tdir
24710         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24711         createmany -o $DIR/$tdir/striped_dir/f 512
24712         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24713         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24714
24715         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24716                 sed "s/[/][^:]*://g")
24717
24718         rm -f $DIR/$tdir/striped_dir/f1*
24719         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24720         removed=$((512 - cnt))
24721
24722         # few files have been just removed, so we expect
24723         # rmfid to fail on their fids
24724         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24725         [ $removed != $errors ] && error "$errors != $removed"
24726
24727         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24728         rm -rf $DIR/$tdir
24729         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24730 }
24731 run_test 421g "rmfid to return errors properly"
24732
24733 test_422() {
24734         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24735         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24736         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24737         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24738         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24739
24740         local amc=$(at_max_get client)
24741         local amo=$(at_max_get mds1)
24742         local timeout=`lctl get_param -n timeout`
24743
24744         at_max_set 0 client
24745         at_max_set 0 mds1
24746
24747 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24748         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24749                         fail_val=$(((2*timeout + 10)*1000))
24750         touch $DIR/$tdir/d3/file &
24751         sleep 2
24752 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24753         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24754                         fail_val=$((2*timeout + 5))
24755         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24756         local pid=$!
24757         sleep 1
24758         kill -9 $pid
24759         sleep $((2 * timeout))
24760         echo kill $pid
24761         kill -9 $pid
24762         lctl mark touch
24763         touch $DIR/$tdir/d2/file3
24764         touch $DIR/$tdir/d2/file4
24765         touch $DIR/$tdir/d2/file5
24766
24767         wait
24768         at_max_set $amc client
24769         at_max_set $amo mds1
24770
24771         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24772         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24773                 error "Watchdog is always throttled"
24774 }
24775 run_test 422 "kill a process with RPC in progress"
24776
24777 stat_test() {
24778     df -h $MOUNT &
24779     df -h $MOUNT &
24780     df -h $MOUNT &
24781     df -h $MOUNT &
24782     df -h $MOUNT &
24783     df -h $MOUNT &
24784 }
24785
24786 test_423() {
24787     local _stats
24788     # ensure statfs cache is expired
24789     sleep 2;
24790
24791     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24792     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24793
24794     return 0
24795 }
24796 run_test 423 "statfs should return a right data"
24797
24798 test_424() {
24799 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24800         $LCTL set_param fail_loc=0x80000522
24801         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24802         rm -f $DIR/$tfile
24803 }
24804 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24805
24806 test_425() {
24807         test_mkdir -c -1 $DIR/$tdir
24808         $LFS setstripe -c -1 $DIR/$tdir
24809
24810         lru_resize_disable "" 100
24811         stack_trap "lru_resize_enable" EXIT
24812
24813         sleep 5
24814
24815         for i in $(seq $((MDSCOUNT * 125))); do
24816                 local t=$DIR/$tdir/$tfile_$i
24817
24818                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24819                         error_noexit "Create file $t"
24820         done
24821         stack_trap "rm -rf $DIR/$tdir" EXIT
24822
24823         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24824                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24825                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24826
24827                 [ $lock_count -le $lru_size ] ||
24828                         error "osc lock count $lock_count > lru size $lru_size"
24829         done
24830
24831         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24832                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24833                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24834
24835                 [ $lock_count -le $lru_size ] ||
24836                         error "mdc lock count $lock_count > lru size $lru_size"
24837         done
24838 }
24839 run_test 425 "lock count should not exceed lru size"
24840
24841 test_426() {
24842         splice-test -r $DIR/$tfile
24843         splice-test -rd $DIR/$tfile
24844         splice-test $DIR/$tfile
24845         splice-test -d $DIR/$tfile
24846 }
24847 run_test 426 "splice test on Lustre"
24848
24849 test_427() {
24850         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24851         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24852                 skip "Need MDS version at least 2.12.4"
24853         local log
24854
24855         mkdir $DIR/$tdir
24856         mkdir $DIR/$tdir/1
24857         mkdir $DIR/$tdir/2
24858         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24859         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24860
24861         $LFS getdirstripe $DIR/$tdir/1/dir
24862
24863         #first setfattr for creating updatelog
24864         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24865
24866 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24867         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24868         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24869         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24870
24871         sleep 2
24872         fail mds2
24873         wait_recovery_complete mds2 $((2*TIMEOUT))
24874
24875         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24876         echo $log | grep "get update log failed" &&
24877                 error "update log corruption is detected" || true
24878 }
24879 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24880
24881 test_428() {
24882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24883         local cache_limit=$CACHE_MAX
24884
24885         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24886         $LCTL set_param -n llite.*.max_cached_mb=64
24887
24888         mkdir $DIR/$tdir
24889         $LFS setstripe -c 1 $DIR/$tdir
24890         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24891         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24892         #test write
24893         for f in $(seq 4); do
24894                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24895         done
24896         wait
24897
24898         cancel_lru_locks osc
24899         # Test read
24900         for f in $(seq 4); do
24901                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24902         done
24903         wait
24904 }
24905 run_test 428 "large block size IO should not hang"
24906
24907 test_429() { # LU-7915 / LU-10948
24908         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24909         local testfile=$DIR/$tfile
24910         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24911         local new_flag=1
24912         local first_rpc
24913         local second_rpc
24914         local third_rpc
24915
24916         $LCTL get_param $ll_opencache_threshold_count ||
24917                 skip "client does not have opencache parameter"
24918
24919         set_opencache $new_flag
24920         stack_trap "restore_opencache"
24921         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24922                 error "enable opencache failed"
24923         touch $testfile
24924         # drop MDC DLM locks
24925         cancel_lru_locks mdc
24926         # clear MDC RPC stats counters
24927         $LCTL set_param $mdc_rpcstats=clear
24928
24929         # According to the current implementation, we need to run 3 times
24930         # open & close file to verify if opencache is enabled correctly.
24931         # 1st, RPCs are sent for lookup/open and open handle is released on
24932         #      close finally.
24933         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24934         #      so open handle won't be released thereafter.
24935         # 3rd, No RPC is sent out.
24936         $MULTIOP $testfile oc || error "multiop failed"
24937         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24938         echo "1st: $first_rpc RPCs in flight"
24939
24940         $MULTIOP $testfile oc || error "multiop failed"
24941         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24942         echo "2nd: $second_rpc RPCs in flight"
24943
24944         $MULTIOP $testfile oc || error "multiop failed"
24945         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24946         echo "3rd: $third_rpc RPCs in flight"
24947
24948         #verify no MDC RPC is sent
24949         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
24950 }
24951 run_test 429 "verify if opencache flag on client side does work"
24952
24953 lseek_test_430() {
24954         local offset
24955         local file=$1
24956
24957         # data at [200K, 400K)
24958         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24959                 error "256K->512K dd fails"
24960         # data at [2M, 3M)
24961         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24962                 error "2M->3M dd fails"
24963         # data at [4M, 5M)
24964         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24965                 error "4M->5M dd fails"
24966         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24967         # start at first component hole #1
24968         printf "Seeking hole from 1000 ... "
24969         offset=$(lseek_test -l 1000 $file)
24970         echo $offset
24971         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24972         printf "Seeking data from 1000 ... "
24973         offset=$(lseek_test -d 1000 $file)
24974         echo $offset
24975         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24976
24977         # start at first component data block
24978         printf "Seeking hole from 300000 ... "
24979         offset=$(lseek_test -l 300000 $file)
24980         echo $offset
24981         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24982         printf "Seeking data from 300000 ... "
24983         offset=$(lseek_test -d 300000 $file)
24984         echo $offset
24985         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24986
24987         # start at the first component but beyond end of object size
24988         printf "Seeking hole from 1000000 ... "
24989         offset=$(lseek_test -l 1000000 $file)
24990         echo $offset
24991         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24992         printf "Seeking data from 1000000 ... "
24993         offset=$(lseek_test -d 1000000 $file)
24994         echo $offset
24995         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24996
24997         # start at second component stripe 2 (empty file)
24998         printf "Seeking hole from 1500000 ... "
24999         offset=$(lseek_test -l 1500000 $file)
25000         echo $offset
25001         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25002         printf "Seeking data from 1500000 ... "
25003         offset=$(lseek_test -d 1500000 $file)
25004         echo $offset
25005         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25006
25007         # start at second component stripe 1 (all data)
25008         printf "Seeking hole from 3000000 ... "
25009         offset=$(lseek_test -l 3000000 $file)
25010         echo $offset
25011         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25012         printf "Seeking data from 3000000 ... "
25013         offset=$(lseek_test -d 3000000 $file)
25014         echo $offset
25015         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25016
25017         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25018                 error "2nd dd fails"
25019         echo "Add data block at 640K...1280K"
25020
25021         # start at before new data block, in hole
25022         printf "Seeking hole from 600000 ... "
25023         offset=$(lseek_test -l 600000 $file)
25024         echo $offset
25025         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25026         printf "Seeking data from 600000 ... "
25027         offset=$(lseek_test -d 600000 $file)
25028         echo $offset
25029         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25030
25031         # start at the first component new data block
25032         printf "Seeking hole from 1000000 ... "
25033         offset=$(lseek_test -l 1000000 $file)
25034         echo $offset
25035         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25036         printf "Seeking data from 1000000 ... "
25037         offset=$(lseek_test -d 1000000 $file)
25038         echo $offset
25039         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25040
25041         # start at second component stripe 2, new data
25042         printf "Seeking hole from 1200000 ... "
25043         offset=$(lseek_test -l 1200000 $file)
25044         echo $offset
25045         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25046         printf "Seeking data from 1200000 ... "
25047         offset=$(lseek_test -d 1200000 $file)
25048         echo $offset
25049         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25050
25051         # start beyond file end
25052         printf "Using offset > filesize ... "
25053         lseek_test -l 4000000 $file && error "lseek should fail"
25054         printf "Using offset > filesize ... "
25055         lseek_test -d 4000000 $file && error "lseek should fail"
25056
25057         printf "Done\n\n"
25058 }
25059
25060 test_430a() {
25061         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25062                 skip "MDT does not support SEEK_HOLE"
25063
25064         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25065                 skip "OST does not support SEEK_HOLE"
25066
25067         local file=$DIR/$tdir/$tfile
25068
25069         mkdir -p $DIR/$tdir
25070
25071         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25072         # OST stripe #1 will have continuous data at [1M, 3M)
25073         # OST stripe #2 is empty
25074         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25075         lseek_test_430 $file
25076         rm $file
25077         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25078         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25079         lseek_test_430 $file
25080         rm $file
25081         $LFS setstripe -c2 -S 512K $file
25082         echo "Two stripes, stripe size 512K"
25083         lseek_test_430 $file
25084         rm $file
25085         # FLR with stale mirror
25086         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25087                        -N -c2 -S 1M $file
25088         echo "Mirrored file:"
25089         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25090         echo "Plain 2 stripes 1M"
25091         lseek_test_430 $file
25092         rm $file
25093 }
25094 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25095
25096 test_430b() {
25097         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25098                 skip "OST does not support SEEK_HOLE"
25099
25100         local offset
25101         local file=$DIR/$tdir/$tfile
25102
25103         mkdir -p $DIR/$tdir
25104         # Empty layout lseek should fail
25105         $MCREATE $file
25106         # seek from 0
25107         printf "Seeking hole from 0 ... "
25108         lseek_test -l 0 $file && error "lseek should fail"
25109         printf "Seeking data from 0 ... "
25110         lseek_test -d 0 $file && error "lseek should fail"
25111         rm $file
25112
25113         # 1M-hole file
25114         $LFS setstripe -E 1M -c2 -E eof $file
25115         $TRUNCATE $file 1048576
25116         printf "Seeking hole from 1000000 ... "
25117         offset=$(lseek_test -l 1000000 $file)
25118         echo $offset
25119         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25120         printf "Seeking data from 1000000 ... "
25121         lseek_test -d 1000000 $file && error "lseek should fail"
25122         rm $file
25123
25124         # full component followed by non-inited one
25125         $LFS setstripe -E 1M -c2 -E eof $file
25126         dd if=/dev/urandom of=$file bs=1M count=1
25127         printf "Seeking hole from 1000000 ... "
25128         offset=$(lseek_test -l 1000000 $file)
25129         echo $offset
25130         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25131         printf "Seeking hole from 1048576 ... "
25132         lseek_test -l 1048576 $file && error "lseek should fail"
25133         # init second component and truncate back
25134         echo "123" >> $file
25135         $TRUNCATE $file 1048576
25136         printf "Seeking hole from 1000000 ... "
25137         offset=$(lseek_test -l 1000000 $file)
25138         echo $offset
25139         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25140         printf "Seeking hole from 1048576 ... "
25141         lseek_test -l 1048576 $file && error "lseek should fail"
25142         # boundary checks for big values
25143         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25144         offset=$(lseek_test -d 0 $file.10g)
25145         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25146         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25147         offset=$(lseek_test -d 0 $file.100g)
25148         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25149         return 0
25150 }
25151 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25152
25153 test_430c() {
25154         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25155                 skip "OST does not support SEEK_HOLE"
25156
25157         local file=$DIR/$tdir/$tfile
25158         local start
25159
25160         mkdir -p $DIR/$tdir
25161         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25162
25163         # cp version 8.33+ prefers lseek over fiemap
25164         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25165                 start=$SECONDS
25166                 time cp $file /dev/null
25167                 (( SECONDS - start < 5 )) ||
25168                         error "cp: too long runtime $((SECONDS - start))"
25169
25170         fi
25171         # tar version 1.29+ supports SEEK_HOLE/DATA
25172         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25173                 start=$SECONDS
25174                 time tar cS $file - | cat > /dev/null
25175                 (( SECONDS - start < 5 )) ||
25176                         error "tar: too long runtime $((SECONDS - start))"
25177         fi
25178 }
25179 run_test 430c "lseek: external tools check"
25180
25181 test_431() { # LU-14187
25182         local file=$DIR/$tdir/$tfile
25183
25184         mkdir -p $DIR/$tdir
25185         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25186         dd if=/dev/urandom of=$file bs=4k count=1
25187         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25188         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25189         #define OBD_FAIL_OST_RESTART_IO 0x251
25190         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25191         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25192         cp $file $file.0
25193         cancel_lru_locks
25194         sync_all_data
25195         echo 3 > /proc/sys/vm/drop_caches
25196         diff  $file $file.0 || error "data diff"
25197 }
25198 run_test 431 "Restart transaction for IO"
25199
25200 prep_801() {
25201         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25202         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25203                 skip "Need server version at least 2.9.55"
25204
25205         start_full_debug_logging
25206 }
25207
25208 post_801() {
25209         stop_full_debug_logging
25210 }
25211
25212 barrier_stat() {
25213         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25214                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25215                            awk '/The barrier for/ { print $7 }')
25216                 echo $st
25217         else
25218                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25219                 echo \'$st\'
25220         fi
25221 }
25222
25223 barrier_expired() {
25224         local expired
25225
25226         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25227                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25228                           awk '/will be expired/ { print $7 }')
25229         else
25230                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25231         fi
25232
25233         echo $expired
25234 }
25235
25236 test_801a() {
25237         prep_801
25238
25239         echo "Start barrier_freeze at: $(date)"
25240         #define OBD_FAIL_BARRIER_DELAY          0x2202
25241         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25242         # Do not reduce barrier time - See LU-11873
25243         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25244
25245         sleep 2
25246         local b_status=$(barrier_stat)
25247         echo "Got barrier status at: $(date)"
25248         [ "$b_status" = "'freezing_p1'" ] ||
25249                 error "(1) unexpected barrier status $b_status"
25250
25251         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25252         wait
25253         b_status=$(barrier_stat)
25254         [ "$b_status" = "'frozen'" ] ||
25255                 error "(2) unexpected barrier status $b_status"
25256
25257         local expired=$(barrier_expired)
25258         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25259         sleep $((expired + 3))
25260
25261         b_status=$(barrier_stat)
25262         [ "$b_status" = "'expired'" ] ||
25263                 error "(3) unexpected barrier status $b_status"
25264
25265         # Do not reduce barrier time - See LU-11873
25266         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25267                 error "(4) fail to freeze barrier"
25268
25269         b_status=$(barrier_stat)
25270         [ "$b_status" = "'frozen'" ] ||
25271                 error "(5) unexpected barrier status $b_status"
25272
25273         echo "Start barrier_thaw at: $(date)"
25274         #define OBD_FAIL_BARRIER_DELAY          0x2202
25275         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25276         do_facet mgs $LCTL barrier_thaw $FSNAME &
25277
25278         sleep 2
25279         b_status=$(barrier_stat)
25280         echo "Got barrier status at: $(date)"
25281         [ "$b_status" = "'thawing'" ] ||
25282                 error "(6) unexpected barrier status $b_status"
25283
25284         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25285         wait
25286         b_status=$(barrier_stat)
25287         [ "$b_status" = "'thawed'" ] ||
25288                 error "(7) unexpected barrier status $b_status"
25289
25290         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25291         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25292         do_facet mgs $LCTL barrier_freeze $FSNAME
25293
25294         b_status=$(barrier_stat)
25295         [ "$b_status" = "'failed'" ] ||
25296                 error "(8) unexpected barrier status $b_status"
25297
25298         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25299         do_facet mgs $LCTL barrier_thaw $FSNAME
25300
25301         post_801
25302 }
25303 run_test 801a "write barrier user interfaces and stat machine"
25304
25305 test_801b() {
25306         prep_801
25307
25308         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25309         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25310         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25311         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25312         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25313
25314         cancel_lru_locks mdc
25315
25316         # 180 seconds should be long enough
25317         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25318
25319         local b_status=$(barrier_stat)
25320         [ "$b_status" = "'frozen'" ] ||
25321                 error "(6) unexpected barrier status $b_status"
25322
25323         mkdir $DIR/$tdir/d0/d10 &
25324         mkdir_pid=$!
25325
25326         touch $DIR/$tdir/d1/f13 &
25327         touch_pid=$!
25328
25329         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25330         ln_pid=$!
25331
25332         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25333         mv_pid=$!
25334
25335         rm -f $DIR/$tdir/d4/f12 &
25336         rm_pid=$!
25337
25338         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25339
25340         # To guarantee taht the 'stat' is not blocked
25341         b_status=$(barrier_stat)
25342         [ "$b_status" = "'frozen'" ] ||
25343                 error "(8) unexpected barrier status $b_status"
25344
25345         # let above commands to run at background
25346         sleep 5
25347
25348         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25349         ps -p $touch_pid || error "(10) touch should be blocked"
25350         ps -p $ln_pid || error "(11) link should be blocked"
25351         ps -p $mv_pid || error "(12) rename should be blocked"
25352         ps -p $rm_pid || error "(13) unlink should be blocked"
25353
25354         b_status=$(barrier_stat)
25355         [ "$b_status" = "'frozen'" ] ||
25356                 error "(14) unexpected barrier status $b_status"
25357
25358         do_facet mgs $LCTL barrier_thaw $FSNAME
25359         b_status=$(barrier_stat)
25360         [ "$b_status" = "'thawed'" ] ||
25361                 error "(15) unexpected barrier status $b_status"
25362
25363         wait $mkdir_pid || error "(16) mkdir should succeed"
25364         wait $touch_pid || error "(17) touch should succeed"
25365         wait $ln_pid || error "(18) link should succeed"
25366         wait $mv_pid || error "(19) rename should succeed"
25367         wait $rm_pid || error "(20) unlink should succeed"
25368
25369         post_801
25370 }
25371 run_test 801b "modification will be blocked by write barrier"
25372
25373 test_801c() {
25374         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25375
25376         prep_801
25377
25378         stop mds2 || error "(1) Fail to stop mds2"
25379
25380         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25381
25382         local b_status=$(barrier_stat)
25383         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25384                 do_facet mgs $LCTL barrier_thaw $FSNAME
25385                 error "(2) unexpected barrier status $b_status"
25386         }
25387
25388         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25389                 error "(3) Fail to rescan barrier bitmap"
25390
25391         # Do not reduce barrier time - See LU-11873
25392         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25393
25394         b_status=$(barrier_stat)
25395         [ "$b_status" = "'frozen'" ] ||
25396                 error "(4) unexpected barrier status $b_status"
25397
25398         do_facet mgs $LCTL barrier_thaw $FSNAME
25399         b_status=$(barrier_stat)
25400         [ "$b_status" = "'thawed'" ] ||
25401                 error "(5) unexpected barrier status $b_status"
25402
25403         local devname=$(mdsdevname 2)
25404
25405         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25406
25407         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25408                 error "(7) Fail to rescan barrier bitmap"
25409
25410         post_801
25411 }
25412 run_test 801c "rescan barrier bitmap"
25413
25414 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25415 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25416 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25417 saved_MOUNT_OPTS=$MOUNT_OPTS
25418
25419 cleanup_802a() {
25420         trap 0
25421
25422         stopall
25423         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25424         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25425         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25426         MOUNT_OPTS=$saved_MOUNT_OPTS
25427         setupall
25428 }
25429
25430 test_802a() {
25431         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25432         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25433         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25434                 skip "Need server version at least 2.9.55"
25435
25436         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25437
25438         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25439
25440         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25441                 error "(2) Fail to copy"
25442
25443         trap cleanup_802a EXIT
25444
25445         # sync by force before remount as readonly
25446         sync; sync_all_data; sleep 3; sync_all_data
25447
25448         stopall
25449
25450         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25451         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25452         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25453
25454         echo "Mount the server as read only"
25455         setupall server_only || error "(3) Fail to start servers"
25456
25457         echo "Mount client without ro should fail"
25458         mount_client $MOUNT &&
25459                 error "(4) Mount client without 'ro' should fail"
25460
25461         echo "Mount client with ro should succeed"
25462         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25463         mount_client $MOUNT ||
25464                 error "(5) Mount client with 'ro' should succeed"
25465
25466         echo "Modify should be refused"
25467         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25468
25469         echo "Read should be allowed"
25470         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25471                 error "(7) Read should succeed under ro mode"
25472
25473         cleanup_802a
25474 }
25475 run_test 802a "simulate readonly device"
25476
25477 test_802b() {
25478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25479         remote_mds_nodsh && skip "remote MDS with nodsh"
25480
25481         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25482                 skip "readonly option not available"
25483
25484         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25485
25486         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25487                 error "(2) Fail to copy"
25488
25489         # write back all cached data before setting MDT to readonly
25490         cancel_lru_locks
25491         sync_all_data
25492
25493         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25494         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25495
25496         echo "Modify should be refused"
25497         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25498
25499         echo "Read should be allowed"
25500         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25501                 error "(7) Read should succeed under ro mode"
25502
25503         # disable readonly
25504         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25505 }
25506 run_test 802b "be able to set MDTs to readonly"
25507
25508 test_803a() {
25509         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25510         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25511                 skip "MDS needs to be newer than 2.10.54"
25512
25513         mkdir -p $DIR/$tdir
25514         # Create some objects on all MDTs to trigger related logs objects
25515         for idx in $(seq $MDSCOUNT); do
25516                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25517                         $DIR/$tdir/dir${idx} ||
25518                         error "Fail to create $DIR/$tdir/dir${idx}"
25519         done
25520
25521         sync; sleep 3
25522         wait_delete_completed # ensure old test cleanups are finished
25523         echo "before create:"
25524         $LFS df -i $MOUNT
25525         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25526
25527         for i in {1..10}; do
25528                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25529                         error "Fail to create $DIR/$tdir/foo$i"
25530         done
25531
25532         sync; sleep 3
25533         echo "after create:"
25534         $LFS df -i $MOUNT
25535         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25536
25537         # allow for an llog to be cleaned up during the test
25538         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25539                 error "before ($before_used) + 10 > after ($after_used)"
25540
25541         for i in {1..10}; do
25542                 rm -rf $DIR/$tdir/foo$i ||
25543                         error "Fail to remove $DIR/$tdir/foo$i"
25544         done
25545
25546         sleep 3 # avoid MDT return cached statfs
25547         wait_delete_completed
25548         echo "after unlink:"
25549         $LFS df -i $MOUNT
25550         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25551
25552         # allow for an llog to be created during the test
25553         [ $after_used -le $((before_used + 1)) ] ||
25554                 error "after ($after_used) > before ($before_used) + 1"
25555 }
25556 run_test 803a "verify agent object for remote object"
25557
25558 test_803b() {
25559         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25560         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25561                 skip "MDS needs to be newer than 2.13.56"
25562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25563
25564         for i in $(seq 0 $((MDSCOUNT - 1))); do
25565                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25566         done
25567
25568         local before=0
25569         local after=0
25570
25571         local tmp
25572
25573         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25574         for i in $(seq 0 $((MDSCOUNT - 1))); do
25575                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25576                         awk '/getattr/ { print $2 }')
25577                 before=$((before + tmp))
25578         done
25579         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25580         for i in $(seq 0 $((MDSCOUNT - 1))); do
25581                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25582                         awk '/getattr/ { print $2 }')
25583                 after=$((after + tmp))
25584         done
25585
25586         [ $before -eq $after ] || error "getattr count $before != $after"
25587 }
25588 run_test 803b "remote object can getattr from cache"
25589
25590 test_804() {
25591         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25592         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25593                 skip "MDS needs to be newer than 2.10.54"
25594         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25595
25596         mkdir -p $DIR/$tdir
25597         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25598                 error "Fail to create $DIR/$tdir/dir0"
25599
25600         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25601         local dev=$(mdsdevname 2)
25602
25603         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25604                 grep ${fid} || error "NOT found agent entry for dir0"
25605
25606         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25607                 error "Fail to create $DIR/$tdir/dir1"
25608
25609         touch $DIR/$tdir/dir1/foo0 ||
25610                 error "Fail to create $DIR/$tdir/dir1/foo0"
25611         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25612         local rc=0
25613
25614         for idx in $(seq $MDSCOUNT); do
25615                 dev=$(mdsdevname $idx)
25616                 do_facet mds${idx} \
25617                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25618                         grep ${fid} && rc=$idx
25619         done
25620
25621         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25622                 error "Fail to rename foo0 to foo1"
25623         if [ $rc -eq 0 ]; then
25624                 for idx in $(seq $MDSCOUNT); do
25625                         dev=$(mdsdevname $idx)
25626                         do_facet mds${idx} \
25627                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25628                         grep ${fid} && rc=$idx
25629                 done
25630         fi
25631
25632         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25633                 error "Fail to rename foo1 to foo2"
25634         if [ $rc -eq 0 ]; then
25635                 for idx in $(seq $MDSCOUNT); do
25636                         dev=$(mdsdevname $idx)
25637                         do_facet mds${idx} \
25638                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25639                         grep ${fid} && rc=$idx
25640                 done
25641         fi
25642
25643         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25644
25645         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25646                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25647         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25648                 error "Fail to rename foo2 to foo0"
25649         unlink $DIR/$tdir/dir1/foo0 ||
25650                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25651         rm -rf $DIR/$tdir/dir0 ||
25652                 error "Fail to rm $DIR/$tdir/dir0"
25653
25654         for idx in $(seq $MDSCOUNT); do
25655                 dev=$(mdsdevname $idx)
25656                 rc=0
25657
25658                 stop mds${idx}
25659                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25660                         rc=$?
25661                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25662                         error "mount mds$idx failed"
25663                 df $MOUNT > /dev/null 2>&1
25664
25665                 # e2fsck should not return error
25666                 [ $rc -eq 0 ] ||
25667                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25668         done
25669 }
25670 run_test 804 "verify agent entry for remote entry"
25671
25672 cleanup_805() {
25673         do_facet $SINGLEMDS zfs set quota=$old $fsset
25674         unlinkmany $DIR/$tdir/f- 1000000
25675         trap 0
25676 }
25677
25678 test_805() {
25679         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25680         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25681         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25682                 skip "netfree not implemented before 0.7"
25683         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25684                 skip "Need MDS version at least 2.10.57"
25685
25686         local fsset
25687         local freekb
25688         local usedkb
25689         local old
25690         local quota
25691         local pref="osd-zfs.$FSNAME-MDT0000."
25692
25693         # limit available space on MDS dataset to meet nospace issue
25694         # quickly. then ZFS 0.7.2 can use reserved space if asked
25695         # properly (using netfree flag in osd_declare_destroy()
25696         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25697         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25698                 gawk '{print $3}')
25699         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25700         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25701         let "usedkb=usedkb-freekb"
25702         let "freekb=freekb/2"
25703         if let "freekb > 5000"; then
25704                 let "freekb=5000"
25705         fi
25706         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25707         trap cleanup_805 EXIT
25708         mkdir $DIR/$tdir
25709         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25710                 error "Can't set PFL layout"
25711         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25712         rm -rf $DIR/$tdir || error "not able to remove"
25713         do_facet $SINGLEMDS zfs set quota=$old $fsset
25714         trap 0
25715 }
25716 run_test 805 "ZFS can remove from full fs"
25717
25718 # Size-on-MDS test
25719 check_lsom_data()
25720 {
25721         local file=$1
25722         local expect=$(stat -c %s $file)
25723
25724         check_lsom_size $1 $expect
25725
25726         local blocks=$($LFS getsom -b $file)
25727         expect=$(stat -c %b $file)
25728         [[ $blocks == $expect ]] ||
25729                 error "$file expected blocks: $expect, got: $blocks"
25730 }
25731
25732 check_lsom_size()
25733 {
25734         local size
25735         local expect=$2
25736
25737         cancel_lru_locks mdc
25738
25739         size=$($LFS getsom -s $1)
25740         [[ $size == $expect ]] ||
25741                 error "$file expected size: $expect, got: $size"
25742 }
25743
25744 test_806() {
25745         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25746                 skip "Need MDS version at least 2.11.52"
25747
25748         local bs=1048576
25749
25750         touch $DIR/$tfile || error "touch $tfile failed"
25751
25752         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25753         save_lustre_params client "llite.*.xattr_cache" > $save
25754         lctl set_param llite.*.xattr_cache=0
25755         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25756
25757         # single-threaded write
25758         echo "Test SOM for single-threaded write"
25759         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25760                 error "write $tfile failed"
25761         check_lsom_size $DIR/$tfile $bs
25762
25763         local num=32
25764         local size=$(($num * $bs))
25765         local offset=0
25766         local i
25767
25768         echo "Test SOM for single client multi-threaded($num) write"
25769         $TRUNCATE $DIR/$tfile 0
25770         for ((i = 0; i < $num; i++)); do
25771                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25772                 local pids[$i]=$!
25773                 offset=$((offset + $bs))
25774         done
25775         for (( i=0; i < $num; i++ )); do
25776                 wait ${pids[$i]}
25777         done
25778         check_lsom_size $DIR/$tfile $size
25779
25780         $TRUNCATE $DIR/$tfile 0
25781         for ((i = 0; i < $num; i++)); do
25782                 offset=$((offset - $bs))
25783                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25784                 local pids[$i]=$!
25785         done
25786         for (( i=0; i < $num; i++ )); do
25787                 wait ${pids[$i]}
25788         done
25789         check_lsom_size $DIR/$tfile $size
25790
25791         # multi-client writes
25792         num=$(get_node_count ${CLIENTS//,/ })
25793         size=$(($num * $bs))
25794         offset=0
25795         i=0
25796
25797         echo "Test SOM for multi-client ($num) writes"
25798         $TRUNCATE $DIR/$tfile 0
25799         for client in ${CLIENTS//,/ }; do
25800                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25801                 local pids[$i]=$!
25802                 i=$((i + 1))
25803                 offset=$((offset + $bs))
25804         done
25805         for (( i=0; i < $num; i++ )); do
25806                 wait ${pids[$i]}
25807         done
25808         check_lsom_size $DIR/$tfile $offset
25809
25810         i=0
25811         $TRUNCATE $DIR/$tfile 0
25812         for client in ${CLIENTS//,/ }; do
25813                 offset=$((offset - $bs))
25814                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25815                 local pids[$i]=$!
25816                 i=$((i + 1))
25817         done
25818         for (( i=0; i < $num; i++ )); do
25819                 wait ${pids[$i]}
25820         done
25821         check_lsom_size $DIR/$tfile $size
25822
25823         # verify truncate
25824         echo "Test SOM for truncate"
25825         $TRUNCATE $DIR/$tfile 1048576
25826         check_lsom_size $DIR/$tfile 1048576
25827         $TRUNCATE $DIR/$tfile 1234
25828         check_lsom_size $DIR/$tfile 1234
25829
25830         # verify SOM blocks count
25831         echo "Verify SOM block count"
25832         $TRUNCATE $DIR/$tfile 0
25833         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25834                 error "failed to write file $tfile"
25835         check_lsom_data $DIR/$tfile
25836 }
25837 run_test 806 "Verify Lazy Size on MDS"
25838
25839 test_807() {
25840         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25841         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25842                 skip "Need MDS version at least 2.11.52"
25843
25844         # Registration step
25845         changelog_register || error "changelog_register failed"
25846         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25847         changelog_users $SINGLEMDS | grep -q $cl_user ||
25848                 error "User $cl_user not found in changelog_users"
25849
25850         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25851         save_lustre_params client "llite.*.xattr_cache" > $save
25852         lctl set_param llite.*.xattr_cache=0
25853         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25854
25855         rm -rf $DIR/$tdir || error "rm $tdir failed"
25856         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25857         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25858         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25859         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25860                 error "truncate $tdir/trunc failed"
25861
25862         local bs=1048576
25863         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25864                 error "write $tfile failed"
25865
25866         # multi-client wirtes
25867         local num=$(get_node_count ${CLIENTS//,/ })
25868         local offset=0
25869         local i=0
25870
25871         echo "Test SOM for multi-client ($num) writes"
25872         touch $DIR/$tfile || error "touch $tfile failed"
25873         $TRUNCATE $DIR/$tfile 0
25874         for client in ${CLIENTS//,/ }; do
25875                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25876                 local pids[$i]=$!
25877                 i=$((i + 1))
25878                 offset=$((offset + $bs))
25879         done
25880         for (( i=0; i < $num; i++ )); do
25881                 wait ${pids[$i]}
25882         done
25883
25884         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25885         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25886         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25887         check_lsom_data $DIR/$tdir/trunc
25888         check_lsom_data $DIR/$tdir/single_dd
25889         check_lsom_data $DIR/$tfile
25890
25891         rm -rf $DIR/$tdir
25892         # Deregistration step
25893         changelog_deregister || error "changelog_deregister failed"
25894 }
25895 run_test 807 "verify LSOM syncing tool"
25896
25897 check_som_nologged()
25898 {
25899         local lines=$($LFS changelog $FSNAME-MDT0000 |
25900                 grep 'x=trusted.som' | wc -l)
25901         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25902 }
25903
25904 test_808() {
25905         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25906                 skip "Need MDS version at least 2.11.55"
25907
25908         # Registration step
25909         changelog_register || error "changelog_register failed"
25910
25911         touch $DIR/$tfile || error "touch $tfile failed"
25912         check_som_nologged
25913
25914         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25915                 error "write $tfile failed"
25916         check_som_nologged
25917
25918         $TRUNCATE $DIR/$tfile 1234
25919         check_som_nologged
25920
25921         $TRUNCATE $DIR/$tfile 1048576
25922         check_som_nologged
25923
25924         # Deregistration step
25925         changelog_deregister || error "changelog_deregister failed"
25926 }
25927 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25928
25929 check_som_nodata()
25930 {
25931         $LFS getsom $1
25932         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25933 }
25934
25935 test_809() {
25936         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25937                 skip "Need MDS version at least 2.11.56"
25938
25939         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25940                 error "failed to create DoM-only file $DIR/$tfile"
25941         touch $DIR/$tfile || error "touch $tfile failed"
25942         check_som_nodata $DIR/$tfile
25943
25944         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25945                 error "write $tfile failed"
25946         check_som_nodata $DIR/$tfile
25947
25948         $TRUNCATE $DIR/$tfile 1234
25949         check_som_nodata $DIR/$tfile
25950
25951         $TRUNCATE $DIR/$tfile 4097
25952         check_som_nodata $DIR/$file
25953 }
25954 run_test 809 "Verify no SOM xattr store for DoM-only files"
25955
25956 test_810() {
25957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25958         $GSS && skip_env "could not run with gss"
25959         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25960                 skip "OST < 2.12.58 doesn't align checksum"
25961
25962         set_checksums 1
25963         stack_trap "set_checksums $ORIG_CSUM" EXIT
25964         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25965
25966         local csum
25967         local before
25968         local after
25969         for csum in $CKSUM_TYPES; do
25970                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25971                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25972                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25973                         eval set -- $i
25974                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25975                         before=$(md5sum $DIR/$tfile)
25976                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25977                         after=$(md5sum $DIR/$tfile)
25978                         [ "$before" == "$after" ] ||
25979                                 error "$csum: $before != $after bs=$1 seek=$2"
25980                 done
25981         done
25982 }
25983 run_test 810 "partial page writes on ZFS (LU-11663)"
25984
25985 test_812a() {
25986         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25987                 skip "OST < 2.12.51 doesn't support this fail_loc"
25988
25989         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25990         # ensure ost1 is connected
25991         stat $DIR/$tfile >/dev/null || error "can't stat"
25992         wait_osc_import_state client ost1 FULL
25993         # no locks, no reqs to let the connection idle
25994         cancel_lru_locks osc
25995
25996         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25997 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25998         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25999         wait_osc_import_state client ost1 CONNECTING
26000         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26001
26002         stat $DIR/$tfile >/dev/null || error "can't stat file"
26003 }
26004 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26005
26006 test_812b() { # LU-12378
26007         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26008                 skip "OST < 2.12.51 doesn't support this fail_loc"
26009
26010         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26011         # ensure ost1 is connected
26012         stat $DIR/$tfile >/dev/null || error "can't stat"
26013         wait_osc_import_state client ost1 FULL
26014         # no locks, no reqs to let the connection idle
26015         cancel_lru_locks osc
26016
26017         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26018 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26019         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26020         wait_osc_import_state client ost1 CONNECTING
26021         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26022
26023         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26024         wait_osc_import_state client ost1 IDLE
26025 }
26026 run_test 812b "do not drop no resend request for idle connect"
26027
26028 test_812c() {
26029         local old
26030
26031         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26032
26033         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26034         $LFS getstripe $DIR/$tfile
26035         $LCTL set_param osc.*.idle_timeout=10
26036         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26037         # ensure ost1 is connected
26038         stat $DIR/$tfile >/dev/null || error "can't stat"
26039         wait_osc_import_state client ost1 FULL
26040         # no locks, no reqs to let the connection idle
26041         cancel_lru_locks osc
26042
26043 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26044         $LCTL set_param fail_loc=0x80000533
26045         sleep 15
26046         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26047 }
26048 run_test 812c "idle import vs lock enqueue race"
26049
26050 test_813() {
26051         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26052         [ -z "$file_heat_sav" ] && skip "no file heat support"
26053
26054         local readsample
26055         local writesample
26056         local readbyte
26057         local writebyte
26058         local readsample1
26059         local writesample1
26060         local readbyte1
26061         local writebyte1
26062
26063         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26064         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26065
26066         $LCTL set_param -n llite.*.file_heat=1
26067         echo "Turn on file heat"
26068         echo "Period second: $period_second, Decay percentage: $decay_pct"
26069
26070         echo "QQQQ" > $DIR/$tfile
26071         echo "QQQQ" > $DIR/$tfile
26072         echo "QQQQ" > $DIR/$tfile
26073         cat $DIR/$tfile > /dev/null
26074         cat $DIR/$tfile > /dev/null
26075         cat $DIR/$tfile > /dev/null
26076         cat $DIR/$tfile > /dev/null
26077
26078         local out=$($LFS heat_get $DIR/$tfile)
26079
26080         $LFS heat_get $DIR/$tfile
26081         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26082         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26083         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26084         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26085
26086         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26087         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26088         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26089         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26090
26091         sleep $((period_second + 3))
26092         echo "Sleep $((period_second + 3)) seconds..."
26093         # The recursion formula to calculate the heat of the file f is as
26094         # follow:
26095         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26096         # Where Hi is the heat value in the period between time points i*I and
26097         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26098         # to the weight of Ci.
26099         out=$($LFS heat_get $DIR/$tfile)
26100         $LFS heat_get $DIR/$tfile
26101         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26102         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26103         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26104         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26105
26106         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26107                 error "read sample ($readsample) is wrong"
26108         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26109                 error "write sample ($writesample) is wrong"
26110         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26111                 error "read bytes ($readbyte) is wrong"
26112         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26113                 error "write bytes ($writebyte) is wrong"
26114
26115         echo "QQQQ" > $DIR/$tfile
26116         echo "QQQQ" > $DIR/$tfile
26117         echo "QQQQ" > $DIR/$tfile
26118         cat $DIR/$tfile > /dev/null
26119         cat $DIR/$tfile > /dev/null
26120         cat $DIR/$tfile > /dev/null
26121         cat $DIR/$tfile > /dev/null
26122
26123         sleep $((period_second + 3))
26124         echo "Sleep $((period_second + 3)) seconds..."
26125
26126         out=$($LFS heat_get $DIR/$tfile)
26127         $LFS heat_get $DIR/$tfile
26128         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26129         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26130         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26131         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26132
26133         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26134                 4 * $decay_pct) / 100") -eq 1 ] ||
26135                 error "read sample ($readsample1) is wrong"
26136         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26137                 3 * $decay_pct) / 100") -eq 1 ] ||
26138                 error "write sample ($writesample1) is wrong"
26139         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26140                 20 * $decay_pct) / 100") -eq 1 ] ||
26141                 error "read bytes ($readbyte1) is wrong"
26142         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26143                 15 * $decay_pct) / 100") -eq 1 ] ||
26144                 error "write bytes ($writebyte1) is wrong"
26145
26146         echo "Turn off file heat for the file $DIR/$tfile"
26147         $LFS heat_set -o $DIR/$tfile
26148
26149         echo "QQQQ" > $DIR/$tfile
26150         echo "QQQQ" > $DIR/$tfile
26151         echo "QQQQ" > $DIR/$tfile
26152         cat $DIR/$tfile > /dev/null
26153         cat $DIR/$tfile > /dev/null
26154         cat $DIR/$tfile > /dev/null
26155         cat $DIR/$tfile > /dev/null
26156
26157         out=$($LFS heat_get $DIR/$tfile)
26158         $LFS heat_get $DIR/$tfile
26159         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26160         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26161         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26162         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26163
26164         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26165         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26166         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26167         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26168
26169         echo "Trun on file heat for the file $DIR/$tfile"
26170         $LFS heat_set -O $DIR/$tfile
26171
26172         echo "QQQQ" > $DIR/$tfile
26173         echo "QQQQ" > $DIR/$tfile
26174         echo "QQQQ" > $DIR/$tfile
26175         cat $DIR/$tfile > /dev/null
26176         cat $DIR/$tfile > /dev/null
26177         cat $DIR/$tfile > /dev/null
26178         cat $DIR/$tfile > /dev/null
26179
26180         out=$($LFS heat_get $DIR/$tfile)
26181         $LFS heat_get $DIR/$tfile
26182         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26183         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26184         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26185         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26186
26187         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26188         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26189         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26190         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26191
26192         $LFS heat_set -c $DIR/$tfile
26193         $LCTL set_param -n llite.*.file_heat=0
26194         echo "Turn off file heat support for the Lustre filesystem"
26195
26196         echo "QQQQ" > $DIR/$tfile
26197         echo "QQQQ" > $DIR/$tfile
26198         echo "QQQQ" > $DIR/$tfile
26199         cat $DIR/$tfile > /dev/null
26200         cat $DIR/$tfile > /dev/null
26201         cat $DIR/$tfile > /dev/null
26202         cat $DIR/$tfile > /dev/null
26203
26204         out=$($LFS heat_get $DIR/$tfile)
26205         $LFS heat_get $DIR/$tfile
26206         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26207         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26208         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26209         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26210
26211         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26212         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26213         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26214         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26215
26216         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26217         rm -f $DIR/$tfile
26218 }
26219 run_test 813 "File heat verfication"
26220
26221 test_814()
26222 {
26223         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26224         echo -n y >> $DIR/$tfile
26225         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26226         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26227 }
26228 run_test 814 "sparse cp works as expected (LU-12361)"
26229
26230 test_815()
26231 {
26232         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26233         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26234 }
26235 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26236
26237 test_816() {
26238         local ost1_imp=$(get_osc_import_name client ost1)
26239         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26240                          cut -d'.' -f2)
26241
26242         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26243         # ensure ost1 is connected
26244
26245         stat $DIR/$tfile >/dev/null || error "can't stat"
26246         wait_osc_import_state client ost1 FULL
26247         # no locks, no reqs to let the connection idle
26248         cancel_lru_locks osc
26249         lru_resize_disable osc
26250         local before
26251         local now
26252         before=$($LCTL get_param -n \
26253                  ldlm.namespaces.$imp_name.lru_size)
26254
26255         wait_osc_import_state client ost1 IDLE
26256         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26257         now=$($LCTL get_param -n \
26258               ldlm.namespaces.$imp_name.lru_size)
26259         [ $before == $now ] || error "lru_size changed $before != $now"
26260 }
26261 run_test 816 "do not reset lru_resize on idle reconnect"
26262
26263 cleanup_817() {
26264         umount $tmpdir
26265         exportfs -u localhost:$DIR/nfsexp
26266         rm -rf $DIR/nfsexp
26267 }
26268
26269 test_817() {
26270         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26271
26272         mkdir -p $DIR/nfsexp
26273         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26274                 error "failed to export nfs"
26275
26276         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26277         stack_trap cleanup_817 EXIT
26278
26279         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26280                 error "failed to mount nfs to $tmpdir"
26281
26282         cp /bin/true $tmpdir
26283         $DIR/nfsexp/true || error "failed to execute 'true' command"
26284 }
26285 run_test 817 "nfsd won't cache write lock for exec file"
26286
26287 test_818() {
26288         mkdir $DIR/$tdir
26289         $LFS setstripe -c1 -i0 $DIR/$tfile
26290         $LFS setstripe -c1 -i1 $DIR/$tfile
26291         stop $SINGLEMDS
26292         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26293         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26294         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26295                 error "start $SINGLEMDS failed"
26296         rm -rf $DIR/$tdir
26297 }
26298 run_test 818 "unlink with failed llog"
26299
26300 test_819a() {
26301         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26302         cancel_lru_locks osc
26303         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26304         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26305         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26306         rm -f $TDIR/$tfile
26307 }
26308 run_test 819a "too big niobuf in read"
26309
26310 test_819b() {
26311         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26312         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26313         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26314         cancel_lru_locks osc
26315         sleep 1
26316         rm -f $TDIR/$tfile
26317 }
26318 run_test 819b "too big niobuf in write"
26319
26320
26321 function test_820_start_ost() {
26322         sleep 5
26323
26324         for num in $(seq $OSTCOUNT); do
26325                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26326         done
26327 }
26328
26329 test_820() {
26330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26331
26332         mkdir $DIR/$tdir
26333         umount_client $MOUNT || error "umount failed"
26334         for num in $(seq $OSTCOUNT); do
26335                 stop ost$num
26336         done
26337
26338         # mount client with no active OSTs
26339         # so that the client can't initialize max LOV EA size
26340         # from OSC notifications
26341         mount_client $MOUNT || error "mount failed"
26342         # delay OST starting to keep this 0 max EA size for a while
26343         test_820_start_ost &
26344
26345         # create a directory on MDS2
26346         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26347                 error "Failed to create directory"
26348         # open intent should update default EA size
26349         # see mdc_update_max_ea_from_body()
26350         # notice this is the very first RPC to MDS2
26351         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26352         ret=$?
26353         echo $out
26354         # With SSK, this situation can lead to -EPERM being returned.
26355         # In that case, simply retry.
26356         if [ $ret -ne 0 ] && $SHARED_KEY; then
26357                 if echo "$out" | grep -q "not permitted"; then
26358                         cp /etc/services $DIR/$tdir/mds2
26359                         ret=$?
26360                 fi
26361         fi
26362         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26363 }
26364 run_test 820 "update max EA from open intent"
26365
26366 test_822() {
26367         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26368
26369         save_lustre_params mds1 \
26370                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26371         do_facet $SINGLEMDS "$LCTL set_param -n \
26372                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26373         do_facet $SINGLEMDS "$LCTL set_param -n \
26374                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26375
26376         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26377         local maxage=$(do_facet mds1 $LCTL get_param -n \
26378                        osp.$FSNAME-OST0000*MDT0000.maxage)
26379         sleep $((maxage + 1))
26380
26381         #define OBD_FAIL_NET_ERROR_RPC          0x532
26382         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26383
26384         stack_trap "restore_lustre_params < $p; rm $p"
26385
26386         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26387                       osp.$FSNAME-OST0000*MDT0000.create_count")
26388         for i in $(seq 1 $count); do
26389                 touch $DIR/$tfile.${i} || error "touch failed"
26390         done
26391 }
26392 run_test 822 "test precreate failure"
26393
26394 #
26395 # tests that do cleanup/setup should be run at the end
26396 #
26397
26398 test_900() {
26399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26400         local ls
26401
26402         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26403         $LCTL set_param fail_loc=0x903
26404
26405         cancel_lru_locks MGC
26406
26407         FAIL_ON_ERROR=true cleanup
26408         FAIL_ON_ERROR=true setup
26409 }
26410 run_test 900 "umount should not race with any mgc requeue thread"
26411
26412 # LUS-6253/LU-11185
26413 test_901() {
26414         local oldc
26415         local newc
26416         local olds
26417         local news
26418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26419
26420         # some get_param have a bug to handle dot in param name
26421         cancel_lru_locks MGC
26422         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26423         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26424         umount_client $MOUNT || error "umount failed"
26425         mount_client $MOUNT || error "mount failed"
26426         cancel_lru_locks MGC
26427         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26428         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26429
26430         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26431         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26432
26433         return 0
26434 }
26435 run_test 901 "don't leak a mgc lock on client umount"
26436
26437 # LU-13377
26438 test_902() {
26439         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26440                 skip "client does not have LU-13377 fix"
26441         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26442         $LCTL set_param fail_loc=0x1415
26443         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26444         cancel_lru_locks osc
26445         rm -f $DIR/$tfile
26446 }
26447 run_test 902 "test short write doesn't hang lustre"
26448
26449 complete $SECONDS
26450 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26451 check_and_cleanup_lustre
26452 if [ "$I_MOUNTED" != "yes" ]; then
26453         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26454 fi
26455 exit_status