Whamcloud - gitweb
LU-10350 lod: adjust stripe count to available ost count
[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         stack_trap "rm -f $TMP/$tfile*"
3325
3326         test_mkdir $DIR/$tdir-1
3327         test_mkdir $DIR/$tdir-2
3328
3329         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3330         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3333         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3334
3335         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3336         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3337
3338         # Create some bad symlinks and ensure that we don't loop
3339         # forever or something. These should return ELOOP (40) and
3340         # ENOENT (2) but I don't want to test for that because there's
3341         # always some weirdo architecture that needs to ruin
3342         # everything by defining these error numbers differently.
3343
3344         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3345         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3346
3347         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3348         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3349
3350         return 0
3351 }
3352 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3353
3354 # createtest also checks that device nodes are created and
3355 # then visible correctly (#2091)
3356 test_28() { # bug 2091
3357         test_mkdir $DIR/d28
3358         $CREATETEST $DIR/d28/ct || error "createtest failed"
3359 }
3360 run_test 28 "create/mknod/mkdir with bad file types ============"
3361
3362 test_29() {
3363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3364
3365         sync; sleep 1; sync # flush out any dirty pages from previous tests
3366         cancel_lru_locks
3367         test_mkdir $DIR/d29
3368         touch $DIR/d29/foo
3369         log 'first d29'
3370         ls -l $DIR/d29
3371
3372         declare -i LOCKCOUNTORIG=0
3373         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3374                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3375         done
3376         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3377
3378         declare -i LOCKUNUSEDCOUNTORIG=0
3379         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3380                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3381         done
3382
3383         log 'second d29'
3384         ls -l $DIR/d29
3385         log 'done'
3386
3387         declare -i LOCKCOUNTCURRENT=0
3388         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3389                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3390         done
3391
3392         declare -i LOCKUNUSEDCOUNTCURRENT=0
3393         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3394                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3395         done
3396
3397         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3398                 $LCTL set_param -n ldlm.dump_namespaces ""
3399                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3400                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3401                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3402                 return 2
3403         fi
3404         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3405                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3406                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3407                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3408                 return 3
3409         fi
3410 }
3411 run_test 29 "IT_GETATTR regression  ============================"
3412
3413 test_30a() { # was test_30
3414         cp $(which ls) $DIR || cp /bin/ls $DIR
3415         $DIR/ls / || error "Can't execute binary from lustre"
3416         rm $DIR/ls
3417 }
3418 run_test 30a "execute binary from Lustre (execve) =============="
3419
3420 test_30b() {
3421         cp `which ls` $DIR || cp /bin/ls $DIR
3422         chmod go+rx $DIR/ls
3423         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3424         rm $DIR/ls
3425 }
3426 run_test 30b "execute binary from Lustre as non-root ==========="
3427
3428 test_30c() { # b=22376
3429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3430
3431         cp $(which ls) $DIR || cp /bin/ls $DIR
3432         chmod a-rw $DIR/ls
3433         cancel_lru_locks mdc
3434         cancel_lru_locks osc
3435         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3436         rm -f $DIR/ls
3437 }
3438 run_test 30c "execute binary from Lustre without read perms ===="
3439
3440 test_30d() {
3441         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3442
3443         for i in {1..10}; do
3444                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3445                 local PID=$!
3446                 sleep 1
3447                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3448                 wait $PID || error "executing dd from Lustre failed"
3449                 rm -f $DIR/$tfile
3450         done
3451
3452         rm -f $DIR/dd
3453 }
3454 run_test 30d "execute binary from Lustre while clear locks"
3455
3456 test_31a() {
3457         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3458         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3459 }
3460 run_test 31a "open-unlink file =================================="
3461
3462 test_31b() {
3463         touch $DIR/f31 || error "touch $DIR/f31 failed"
3464         ln $DIR/f31 $DIR/f31b || error "ln failed"
3465         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3466         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3467 }
3468 run_test 31b "unlink file with multiple links while open ======="
3469
3470 test_31c() {
3471         touch $DIR/f31 || error "touch $DIR/f31 failed"
3472         ln $DIR/f31 $DIR/f31c || error "ln failed"
3473         multiop_bg_pause $DIR/f31 O_uc ||
3474                 error "multiop_bg_pause for $DIR/f31 failed"
3475         MULTIPID=$!
3476         $MULTIOP $DIR/f31c Ouc
3477         kill -USR1 $MULTIPID
3478         wait $MULTIPID
3479 }
3480 run_test 31c "open-unlink file with multiple links ============="
3481
3482 test_31d() {
3483         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3484         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3485 }
3486 run_test 31d "remove of open directory ========================="
3487
3488 test_31e() { # bug 2904
3489         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3490 }
3491 run_test 31e "remove of open non-empty directory ==============="
3492
3493 test_31f() { # bug 4554
3494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3495
3496         set -vx
3497         test_mkdir $DIR/d31f
3498         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3499         cp /etc/hosts $DIR/d31f
3500         ls -l $DIR/d31f
3501         $LFS getstripe $DIR/d31f/hosts
3502         multiop_bg_pause $DIR/d31f D_c || return 1
3503         MULTIPID=$!
3504
3505         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3506         test_mkdir $DIR/d31f
3507         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3508         cp /etc/hosts $DIR/d31f
3509         ls -l $DIR/d31f
3510         $LFS getstripe $DIR/d31f/hosts
3511         multiop_bg_pause $DIR/d31f D_c || return 1
3512         MULTIPID2=$!
3513
3514         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3515         wait $MULTIPID || error "first opendir $MULTIPID failed"
3516
3517         sleep 6
3518
3519         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3520         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3521         set +vx
3522 }
3523 run_test 31f "remove of open directory with open-unlink file ==="
3524
3525 test_31g() {
3526         echo "-- cross directory link --"
3527         test_mkdir -c1 $DIR/${tdir}ga
3528         test_mkdir -c1 $DIR/${tdir}gb
3529         touch $DIR/${tdir}ga/f
3530         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3531         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3532         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3533         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3534         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3535 }
3536 run_test 31g "cross directory link==============="
3537
3538 test_31h() {
3539         echo "-- cross directory link --"
3540         test_mkdir -c1 $DIR/${tdir}
3541         test_mkdir -c1 $DIR/${tdir}/dir
3542         touch $DIR/${tdir}/f
3543         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3544         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3545         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3546         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3547         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3548 }
3549 run_test 31h "cross directory link under child==============="
3550
3551 test_31i() {
3552         echo "-- cross directory link --"
3553         test_mkdir -c1 $DIR/$tdir
3554         test_mkdir -c1 $DIR/$tdir/dir
3555         touch $DIR/$tdir/dir/f
3556         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3557         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3558         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3559         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3560         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3561 }
3562 run_test 31i "cross directory link under parent==============="
3563
3564 test_31j() {
3565         test_mkdir -c1 -p $DIR/$tdir
3566         test_mkdir -c1 -p $DIR/$tdir/dir1
3567         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3568         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3571         return 0
3572 }
3573 run_test 31j "link for directory==============="
3574
3575 test_31k() {
3576         test_mkdir -c1 -p $DIR/$tdir
3577         touch $DIR/$tdir/s
3578         touch $DIR/$tdir/exist
3579         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3580         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3581         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3582         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3583         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3586         return 0
3587 }
3588 run_test 31k "link to file: the same, non-existing, dir==============="
3589
3590 test_31m() {
3591         mkdir $DIR/d31m
3592         touch $DIR/d31m/s
3593         mkdir $DIR/d31m2
3594         touch $DIR/d31m2/exist
3595         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3596         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3597         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3598         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3601         return 0
3602 }
3603 run_test 31m "link to file: the same, non-existing, dir==============="
3604
3605 test_31n() {
3606         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3607         nlink=$(stat --format=%h $DIR/$tfile)
3608         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3609         local fd=$(free_fd)
3610         local cmd="exec $fd<$DIR/$tfile"
3611         eval $cmd
3612         cmd="exec $fd<&-"
3613         trap "eval $cmd" EXIT
3614         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3615         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3616         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3617         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3618         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3619         eval $cmd
3620 }
3621 run_test 31n "check link count of unlinked file"
3622
3623 link_one() {
3624         local tempfile=$(mktemp $1_XXXXXX)
3625         mlink $tempfile $1 2> /dev/null &&
3626                 echo "$BASHPID: link $tempfile to $1 succeeded"
3627         munlink $tempfile
3628 }
3629
3630 test_31o() { # LU-2901
3631         test_mkdir $DIR/$tdir
3632         for LOOP in $(seq 100); do
3633                 rm -f $DIR/$tdir/$tfile*
3634                 for THREAD in $(seq 8); do
3635                         link_one $DIR/$tdir/$tfile.$LOOP &
3636                 done
3637                 wait
3638                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3639                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3640                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3641                         break || true
3642         done
3643 }
3644 run_test 31o "duplicate hard links with same filename"
3645
3646 test_31p() {
3647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3648
3649         test_mkdir $DIR/$tdir
3650         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3651         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3652
3653         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3654                 error "open unlink test1 failed"
3655         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3656                 error "open unlink test2 failed"
3657
3658         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3659                 error "test1 still exists"
3660         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3661                 error "test2 still exists"
3662 }
3663 run_test 31p "remove of open striped directory"
3664
3665 test_31q() {
3666         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3667
3668         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3669         index=$($LFS getdirstripe -i $DIR/$tdir)
3670         [ $index -eq 3 ] || error "first stripe index $index != 3"
3671         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3672         [ $index -eq 1 ] || error "second stripe index $index != 1"
3673
3674         # when "-c <stripe_count>" is set, the number of MDTs specified after
3675         # "-i" should equal to the stripe count
3676         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3677 }
3678 run_test 31q "create striped directory on specific MDTs"
3679
3680 cleanup_test32_mount() {
3681         local rc=0
3682         trap 0
3683         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3684         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3685         losetup -d $loopdev || true
3686         rm -rf $DIR/$tdir
3687         return $rc
3688 }
3689
3690 test_32a() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692
3693         echo "== more mountpoints and symlinks ================="
3694         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3695         trap cleanup_test32_mount EXIT
3696         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3697         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3698                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3699         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3700                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3701         cleanup_test32_mount
3702 }
3703 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3704
3705 test_32b() {
3706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3707
3708         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3709         trap cleanup_test32_mount EXIT
3710         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3711         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3712                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3713         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3714                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3715         cleanup_test32_mount
3716 }
3717 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3718
3719 test_32c() {
3720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3721
3722         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3723         trap cleanup_test32_mount EXIT
3724         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3725         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3726                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3727         test_mkdir -p $DIR/$tdir/d2/test_dir
3728         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3729                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3730         cleanup_test32_mount
3731 }
3732 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3733
3734 test_32d() {
3735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3736
3737         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3738         trap cleanup_test32_mount EXIT
3739         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3740         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3741                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3742         test_mkdir -p $DIR/$tdir/d2/test_dir
3743         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3744                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3745         cleanup_test32_mount
3746 }
3747 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3748
3749 test_32e() {
3750         rm -fr $DIR/$tdir
3751         test_mkdir -p $DIR/$tdir/tmp
3752         local tmp_dir=$DIR/$tdir/tmp
3753         ln -s $DIR/$tdir $tmp_dir/symlink11
3754         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3755         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3756         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3757 }
3758 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3759
3760 test_32f() {
3761         rm -fr $DIR/$tdir
3762         test_mkdir -p $DIR/$tdir/tmp
3763         local tmp_dir=$DIR/$tdir/tmp
3764         ln -s $DIR/$tdir $tmp_dir/symlink11
3765         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3766         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3767         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3768 }
3769 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3770
3771 test_32g() {
3772         local tmp_dir=$DIR/$tdir/tmp
3773         test_mkdir -p $tmp_dir
3774         test_mkdir $DIR/${tdir}2
3775         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3776         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3777         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3778         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3779         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3780         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3781 }
3782 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3783
3784 test_32h() {
3785         rm -fr $DIR/$tdir $DIR/${tdir}2
3786         tmp_dir=$DIR/$tdir/tmp
3787         test_mkdir -p $tmp_dir
3788         test_mkdir $DIR/${tdir}2
3789         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3790         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3791         ls $tmp_dir/symlink12 || error "listing symlink12"
3792         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3793 }
3794 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3795
3796 test_32i() {
3797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3798
3799         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3800         trap cleanup_test32_mount EXIT
3801         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3802         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3803                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3804         touch $DIR/$tdir/test_file
3805         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3806                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3807         cleanup_test32_mount
3808 }
3809 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3810
3811 test_32j() {
3812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3813
3814         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3815         trap cleanup_test32_mount EXIT
3816         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3817         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3818                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3819         touch $DIR/$tdir/test_file
3820         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3825
3826 test_32k() {
3827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3828
3829         rm -fr $DIR/$tdir
3830         trap cleanup_test32_mount EXIT
3831         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3832         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3833                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3834         test_mkdir -p $DIR/$tdir/d2
3835         touch $DIR/$tdir/d2/test_file || error "touch failed"
3836         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3837                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3838         cleanup_test32_mount
3839 }
3840 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3841
3842 test_32l() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2
3851         touch $DIR/$tdir/d2/test_file || error "touch failed"
3852         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3853                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3854         cleanup_test32_mount
3855 }
3856 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3857
3858 test_32m() {
3859         rm -fr $DIR/d32m
3860         test_mkdir -p $DIR/d32m/tmp
3861         TMP_DIR=$DIR/d32m/tmp
3862         ln -s $DIR $TMP_DIR/symlink11
3863         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3864         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3865                 error "symlink11 not a link"
3866         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3867                 error "symlink01 not a link"
3868 }
3869 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3870
3871 test_32n() {
3872         rm -fr $DIR/d32n
3873         test_mkdir -p $DIR/d32n/tmp
3874         TMP_DIR=$DIR/d32n/tmp
3875         ln -s $DIR $TMP_DIR/symlink11
3876         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3877         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3878         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3879 }
3880 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3881
3882 test_32o() {
3883         touch $DIR/$tfile
3884         test_mkdir -p $DIR/d32o/tmp
3885         TMP_DIR=$DIR/d32o/tmp
3886         ln -s $DIR/$tfile $TMP_DIR/symlink12
3887         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3888         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3889                 error "symlink12 not a link"
3890         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3891         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3892                 error "$DIR/d32o/tmp/symlink12 not file type"
3893         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3894                 error "$DIR/d32o/symlink02 not file type"
3895 }
3896 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3897
3898 test_32p() {
3899         log 32p_1
3900         rm -fr $DIR/d32p
3901         log 32p_2
3902         rm -f $DIR/$tfile
3903         log 32p_3
3904         touch $DIR/$tfile
3905         log 32p_4
3906         test_mkdir -p $DIR/d32p/tmp
3907         log 32p_5
3908         TMP_DIR=$DIR/d32p/tmp
3909         log 32p_6
3910         ln -s $DIR/$tfile $TMP_DIR/symlink12
3911         log 32p_7
3912         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3913         log 32p_8
3914         cat $DIR/d32p/tmp/symlink12 ||
3915                 error "Can't open $DIR/d32p/tmp/symlink12"
3916         log 32p_9
3917         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3918         log 32p_10
3919 }
3920 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3921
3922 test_32q() {
3923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3924
3925         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3926         trap cleanup_test32_mount EXIT
3927         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3928         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3929         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3930                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3931         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3932         cleanup_test32_mount
3933 }
3934 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3935
3936 test_32r() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3940         trap cleanup_test32_mount EXIT
3941         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3942         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3943         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3944                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3945         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3946         cleanup_test32_mount
3947 }
3948 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3949
3950 test_33aa() {
3951         rm -f $DIR/$tfile
3952         touch $DIR/$tfile
3953         chmod 444 $DIR/$tfile
3954         chown $RUNAS_ID $DIR/$tfile
3955         log 33_1
3956         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3957         log 33_2
3958 }
3959 run_test 33aa "write file with mode 444 (should return error)"
3960
3961 test_33a() {
3962         rm -fr $DIR/$tdir
3963         test_mkdir $DIR/$tdir
3964         chown $RUNAS_ID $DIR/$tdir
3965         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3966                 error "$RUNAS create $tdir/$tfile failed"
3967         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3968                 error "open RDWR" || true
3969 }
3970 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3971
3972 test_33b() {
3973         rm -fr $DIR/$tdir
3974         test_mkdir $DIR/$tdir
3975         chown $RUNAS_ID $DIR/$tdir
3976         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3977 }
3978 run_test 33b "test open file with malformed flags (No panic)"
3979
3980 test_33c() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982         remote_ost_nodsh && skip "remote OST with nodsh"
3983
3984         local ostnum
3985         local ostname
3986         local write_bytes
3987         local all_zeros
3988
3989         all_zeros=true
3990         test_mkdir $DIR/$tdir
3991         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3992
3993         sync
3994         for ostnum in $(seq $OSTCOUNT); do
3995                 # test-framework's OST numbering is one-based, while Lustre's
3996                 # is zero-based
3997                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3998                 # check if at least some write_bytes stats are counted
3999                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4000                               obdfilter.$ostname.stats |
4001                               awk '/^write_bytes/ {print $7}' )
4002                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4003                 if (( ${write_bytes:-0} > 0 )); then
4004                         all_zeros=false
4005                         break
4006                 fi
4007         done
4008
4009         $all_zeros || return 0
4010
4011         # Write four bytes
4012         echo foo > $DIR/$tdir/bar
4013         # Really write them
4014         sync
4015
4016         # Total up write_bytes after writing.  We'd better find non-zeros.
4017         for ostnum in $(seq $OSTCOUNT); do
4018                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4019                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4020                               obdfilter/$ostname/stats |
4021                               awk '/^write_bytes/ {print $7}' )
4022                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4023                 if (( ${write_bytes:-0} > 0 )); then
4024                         all_zeros=false
4025                         break
4026                 fi
4027         done
4028
4029         if $all_zeros; then
4030                 for ostnum in $(seq $OSTCOUNT); do
4031                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4032                         echo "Check write_bytes is in obdfilter.*.stats:"
4033                         do_facet ost$ostnum lctl get_param -n \
4034                                 obdfilter.$ostname.stats
4035                 done
4036                 error "OST not keeping write_bytes stats (b=22312)"
4037         fi
4038 }
4039 run_test 33c "test write_bytes stats"
4040
4041 test_33d() {
4042         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4044
4045         local MDTIDX=1
4046         local remote_dir=$DIR/$tdir/remote_dir
4047
4048         test_mkdir $DIR/$tdir
4049         $LFS mkdir -i $MDTIDX $remote_dir ||
4050                 error "create remote directory failed"
4051
4052         touch $remote_dir/$tfile
4053         chmod 444 $remote_dir/$tfile
4054         chown $RUNAS_ID $remote_dir/$tfile
4055
4056         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4057
4058         chown $RUNAS_ID $remote_dir
4059         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4060                                         error "create" || true
4061         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4062                                     error "open RDWR" || true
4063         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4064 }
4065 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4066
4067 test_33e() {
4068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4069
4070         mkdir $DIR/$tdir
4071
4072         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4073         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4074         mkdir $DIR/$tdir/local_dir
4075
4076         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4077         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4078         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4079
4080         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4081                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4082
4083         rmdir $DIR/$tdir/* || error "rmdir failed"
4084
4085         umask 777
4086         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4087         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4088         mkdir $DIR/$tdir/local_dir
4089
4090         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4091         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4092         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4093
4094         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4095                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4096
4097         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4098
4099         umask 000
4100         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4101         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4102         mkdir $DIR/$tdir/local_dir
4103
4104         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4105         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4106         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4107
4108         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4109                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4110 }
4111 run_test 33e "mkdir and striped directory should have same mode"
4112
4113 cleanup_33f() {
4114         trap 0
4115         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4116 }
4117
4118 test_33f() {
4119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4120         remote_mds_nodsh && skip "remote MDS with nodsh"
4121
4122         mkdir $DIR/$tdir
4123         chmod go+rwx $DIR/$tdir
4124         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4125         trap cleanup_33f EXIT
4126
4127         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4128                 error "cannot create striped directory"
4129
4130         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4131                 error "cannot create files in striped directory"
4132
4133         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4134                 error "cannot remove files in striped directory"
4135
4136         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4137                 error "cannot remove striped directory"
4138
4139         cleanup_33f
4140 }
4141 run_test 33f "nonroot user can create, access, and remove a striped directory"
4142
4143 test_33g() {
4144         mkdir -p $DIR/$tdir/dir2
4145
4146         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4147         echo $err
4148         [[ $err =~ "exists" ]] || error "Not exists error"
4149 }
4150 run_test 33g "nonroot user create already existing root created file"
4151
4152 test_33h() {
4153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4154         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4155                 skip "Need MDS version at least 2.13.50"
4156
4157         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4158                 error "mkdir $tdir failed"
4159         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4160
4161         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4162         local index2
4163
4164         for fname in $DIR/$tdir/$tfile.bak \
4165                      $DIR/$tdir/$tfile.SAV \
4166                      $DIR/$tdir/$tfile.orig \
4167                      $DIR/$tdir/$tfile~; do
4168                 touch $fname  || error "touch $fname failed"
4169                 index2=$($LFS getstripe -m $fname)
4170                 [ $index -eq $index2 ] ||
4171                         error "$fname MDT index mismatch $index != $index2"
4172         done
4173
4174         local failed=0
4175         for i in {1..250}; do
4176                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4177                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4178                         touch $fname  || error "touch $fname failed"
4179                         index2=$($LFS getstripe -m $fname)
4180                         if [[ $index != $index2 ]]; then
4181                                 failed=$((failed + 1))
4182                                 echo "$fname MDT index mismatch $index != $index2"
4183                         fi
4184                 done
4185         done
4186         echo "$failed MDT index mismatches"
4187         (( failed < 20 )) || error "MDT index mismatch $failed times"
4188
4189 }
4190 run_test 33h "temp file is located on the same MDT as target"
4191
4192 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4193 test_34a() {
4194         rm -f $DIR/f34
4195         $MCREATE $DIR/f34 || error "mcreate failed"
4196         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4197                 error "getstripe failed"
4198         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4200                 error "getstripe failed"
4201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4203 }
4204 run_test 34a "truncate file that has not been opened ==========="
4205
4206 test_34b() {
4207         [ ! -f $DIR/f34 ] && test_34a
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         $OPENFILE -f O_RDONLY $DIR/f34
4211         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4212                 error "getstripe failed"
4213         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4214                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4215 }
4216 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4217
4218 test_34c() {
4219         [ ! -f $DIR/f34 ] && test_34a
4220         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4221                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4222         $OPENFILE -f O_RDWR $DIR/f34
4223         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4224                 error "$LFS getstripe failed"
4225         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4226                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4227 }
4228 run_test 34c "O_RDWR opening file-with-size works =============="
4229
4230 test_34d() {
4231         [ ! -f $DIR/f34 ] && test_34a
4232         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4233                 error "dd failed"
4234         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4235                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4236         rm $DIR/f34
4237 }
4238 run_test 34d "write to sparse file ============================="
4239
4240 test_34e() {
4241         rm -f $DIR/f34e
4242         $MCREATE $DIR/f34e || error "mcreate failed"
4243         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4244         $CHECKSTAT -s 1000 $DIR/f34e ||
4245                 error "Size of $DIR/f34e not equal to 1000 bytes"
4246         $OPENFILE -f O_RDWR $DIR/f34e
4247         $CHECKSTAT -s 1000 $DIR/f34e ||
4248                 error "Size of $DIR/f34e not equal to 1000 bytes"
4249 }
4250 run_test 34e "create objects, some with size and some without =="
4251
4252 test_34f() { # bug 6242, 6243
4253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4254
4255         SIZE34F=48000
4256         rm -f $DIR/f34f
4257         $MCREATE $DIR/f34f || error "mcreate failed"
4258         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4259         dd if=$DIR/f34f of=$TMP/f34f
4260         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4261         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4262         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4263         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4264         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4265 }
4266 run_test 34f "read from a file with no objects until EOF ======="
4267
4268 test_34g() {
4269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4270
4271         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4272                 error "dd failed"
4273         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4274         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4275                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4276         cancel_lru_locks osc
4277         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4278                 error "wrong size after lock cancel"
4279
4280         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4281         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4282                 error "expanding truncate failed"
4283         cancel_lru_locks osc
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4285                 error "wrong expanded size after lock cancel"
4286 }
4287 run_test 34g "truncate long file ==============================="
4288
4289 test_34h() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         local gid=10
4293         local sz=1000
4294
4295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4296         sync # Flush the cache so that multiop below does not block on cache
4297              # flush when getting the group lock
4298         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4299         MULTIPID=$!
4300
4301         # Since just timed wait is not good enough, let's do a sync write
4302         # that way we are sure enough time for a roundtrip + processing
4303         # passed + 2 seconds of extra margin.
4304         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4305         rm $DIR/${tfile}-1
4306         sleep 2
4307
4308         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4309                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4310                 kill -9 $MULTIPID
4311         fi
4312         wait $MULTIPID
4313         local nsz=`stat -c %s $DIR/$tfile`
4314         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4315 }
4316 run_test 34h "ftruncate file under grouplock should not block"
4317
4318 test_35a() {
4319         cp /bin/sh $DIR/f35a
4320         chmod 444 $DIR/f35a
4321         chown $RUNAS_ID $DIR/f35a
4322         $RUNAS $DIR/f35a && error || true
4323         rm $DIR/f35a
4324 }
4325 run_test 35a "exec file with mode 444 (should return and not leak)"
4326
4327 test_36a() {
4328         rm -f $DIR/f36
4329         utime $DIR/f36 || error "utime failed for MDS"
4330 }
4331 run_test 36a "MDS utime check (mknod, utime)"
4332
4333 test_36b() {
4334         echo "" > $DIR/f36
4335         utime $DIR/f36 || error "utime failed for OST"
4336 }
4337 run_test 36b "OST utime check (open, utime)"
4338
4339 test_36c() {
4340         rm -f $DIR/d36/f36
4341         test_mkdir $DIR/d36
4342         chown $RUNAS_ID $DIR/d36
4343         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4344 }
4345 run_test 36c "non-root MDS utime check (mknod, utime)"
4346
4347 test_36d() {
4348         [ ! -d $DIR/d36 ] && test_36c
4349         echo "" > $DIR/d36/f36
4350         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4351 }
4352 run_test 36d "non-root OST utime check (open, utime)"
4353
4354 test_36e() {
4355         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4356
4357         test_mkdir $DIR/$tdir
4358         touch $DIR/$tdir/$tfile
4359         $RUNAS utime $DIR/$tdir/$tfile &&
4360                 error "utime worked, expected failure" || true
4361 }
4362 run_test 36e "utime on non-owned file (should return error)"
4363
4364 subr_36fh() {
4365         local fl="$1"
4366         local LANG_SAVE=$LANG
4367         local LC_LANG_SAVE=$LC_LANG
4368         export LANG=C LC_LANG=C # for date language
4369
4370         DATESTR="Dec 20  2000"
4371         test_mkdir $DIR/$tdir
4372         lctl set_param fail_loc=$fl
4373         date; date +%s
4374         cp /etc/hosts $DIR/$tdir/$tfile
4375         sync & # write RPC generated with "current" inode timestamp, but delayed
4376         sleep 1
4377         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4378         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4379         cancel_lru_locks $OSC
4380         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4381         date; date +%s
4382         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4383                 echo "BEFORE: $LS_BEFORE" && \
4384                 echo "AFTER : $LS_AFTER" && \
4385                 echo "WANT  : $DATESTR" && \
4386                 error "$DIR/$tdir/$tfile timestamps changed" || true
4387
4388         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4389 }
4390
4391 test_36f() {
4392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4393
4394         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4395         subr_36fh "0x80000214"
4396 }
4397 run_test 36f "utime on file racing with OST BRW write =========="
4398
4399 test_36g() {
4400         remote_ost_nodsh && skip "remote OST with nodsh"
4401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4402         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4403                 skip "Need MDS version at least 2.12.51"
4404
4405         local fmd_max_age
4406         local fmd
4407         local facet="ost1"
4408         local tgt="obdfilter"
4409
4410         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4411
4412         test_mkdir $DIR/$tdir
4413         fmd_max_age=$(do_facet $facet \
4414                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4415                 head -n 1")
4416
4417         echo "FMD max age: ${fmd_max_age}s"
4418         touch $DIR/$tdir/$tfile
4419         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4420                 gawk '{cnt=cnt+$1}  END{print cnt}')
4421         echo "FMD before: $fmd"
4422         [[ $fmd == 0 ]] &&
4423                 error "FMD wasn't create by touch"
4424         sleep $((fmd_max_age + 12))
4425         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4426                 gawk '{cnt=cnt+$1}  END{print cnt}')
4427         echo "FMD after: $fmd"
4428         [[ $fmd == 0 ]] ||
4429                 error "FMD wasn't expired by ping"
4430 }
4431 run_test 36g "FMD cache expiry ====================="
4432
4433 test_36h() {
4434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4435
4436         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4437         subr_36fh "0x80000227"
4438 }
4439 run_test 36h "utime on file racing with OST BRW write =========="
4440
4441 test_36i() {
4442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4443
4444         test_mkdir $DIR/$tdir
4445         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4446
4447         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4448         local new_mtime=$((mtime + 200))
4449
4450         #change Modify time of striped dir
4451         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4452                         error "change mtime failed"
4453
4454         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4455
4456         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4457 }
4458 run_test 36i "change mtime on striped directory"
4459
4460 # test_37 - duplicate with tests 32q 32r
4461
4462 test_38() {
4463         local file=$DIR/$tfile
4464         touch $file
4465         openfile -f O_DIRECTORY $file
4466         local RC=$?
4467         local ENOTDIR=20
4468         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4469         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4470 }
4471 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4472
4473 test_39a() { # was test_39
4474         touch $DIR/$tfile
4475         touch $DIR/${tfile}2
4476 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4479         sleep 2
4480         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4481         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4482                 echo "mtime"
4483                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4484                 echo "atime"
4485                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4486                 echo "ctime"
4487                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4488                 error "O_TRUNC didn't change timestamps"
4489         fi
4490 }
4491 run_test 39a "mtime changed on create"
4492
4493 test_39b() {
4494         test_mkdir -c1 $DIR/$tdir
4495         cp -p /etc/passwd $DIR/$tdir/fopen
4496         cp -p /etc/passwd $DIR/$tdir/flink
4497         cp -p /etc/passwd $DIR/$tdir/funlink
4498         cp -p /etc/passwd $DIR/$tdir/frename
4499         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4500
4501         sleep 1
4502         echo "aaaaaa" >> $DIR/$tdir/fopen
4503         echo "aaaaaa" >> $DIR/$tdir/flink
4504         echo "aaaaaa" >> $DIR/$tdir/funlink
4505         echo "aaaaaa" >> $DIR/$tdir/frename
4506
4507         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4508         local link_new=`stat -c %Y $DIR/$tdir/flink`
4509         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4510         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4511
4512         cat $DIR/$tdir/fopen > /dev/null
4513         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4514         rm -f $DIR/$tdir/funlink2
4515         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4516
4517         for (( i=0; i < 2; i++ )) ; do
4518                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4519                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4520                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4521                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4522
4523                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4524                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4525                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4526                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4527
4528                 cancel_lru_locks $OSC
4529                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4530         done
4531 }
4532 run_test 39b "mtime change on open, link, unlink, rename  ======"
4533
4534 # this should be set to past
4535 TEST_39_MTIME=`date -d "1 year ago" +%s`
4536
4537 # bug 11063
4538 test_39c() {
4539         touch $DIR1/$tfile
4540         sleep 2
4541         local mtime0=`stat -c %Y $DIR1/$tfile`
4542
4543         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4544         local mtime1=`stat -c %Y $DIR1/$tfile`
4545         [ "$mtime1" = $TEST_39_MTIME ] || \
4546                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4547
4548         local d1=`date +%s`
4549         echo hello >> $DIR1/$tfile
4550         local d2=`date +%s`
4551         local mtime2=`stat -c %Y $DIR1/$tfile`
4552         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4553                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4554
4555         mv $DIR1/$tfile $DIR1/$tfile-1
4556
4557         for (( i=0; i < 2; i++ )) ; do
4558                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4559                 [ "$mtime2" = "$mtime3" ] || \
4560                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4561
4562                 cancel_lru_locks $OSC
4563                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4564         done
4565 }
4566 run_test 39c "mtime change on rename ==========================="
4567
4568 # bug 21114
4569 test_39d() {
4570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4571
4572         touch $DIR1/$tfile
4573         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4574
4575         for (( i=0; i < 2; i++ )) ; do
4576                 local mtime=`stat -c %Y $DIR1/$tfile`
4577                 [ $mtime = $TEST_39_MTIME ] || \
4578                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4579
4580                 cancel_lru_locks $OSC
4581                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4582         done
4583 }
4584 run_test 39d "create, utime, stat =============================="
4585
4586 # bug 21114
4587 test_39e() {
4588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4589
4590         touch $DIR1/$tfile
4591         local mtime1=`stat -c %Y $DIR1/$tfile`
4592
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594
4595         for (( i=0; i < 2; i++ )) ; do
4596                 local mtime2=`stat -c %Y $DIR1/$tfile`
4597                 [ $mtime2 = $TEST_39_MTIME ] || \
4598                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4599
4600                 cancel_lru_locks $OSC
4601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4602         done
4603 }
4604 run_test 39e "create, stat, utime, stat ========================"
4605
4606 # bug 21114
4607 test_39f() {
4608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4609
4610         touch $DIR1/$tfile
4611         mtime1=`stat -c %Y $DIR1/$tfile`
4612
4613         sleep 2
4614         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4615
4616         for (( i=0; i < 2; i++ )) ; do
4617                 local mtime2=`stat -c %Y $DIR1/$tfile`
4618                 [ $mtime2 = $TEST_39_MTIME ] || \
4619                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4620
4621                 cancel_lru_locks $OSC
4622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4623         done
4624 }
4625 run_test 39f "create, stat, sleep, utime, stat ================="
4626
4627 # bug 11063
4628 test_39g() {
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         echo hello >> $DIR1/$tfile
4632         local mtime1=`stat -c %Y $DIR1/$tfile`
4633
4634         sleep 2
4635         chmod o+r $DIR1/$tfile
4636
4637         for (( i=0; i < 2; i++ )) ; do
4638                 local mtime2=`stat -c %Y $DIR1/$tfile`
4639                 [ "$mtime1" = "$mtime2" ] || \
4640                         error "lost mtime: $mtime2, should be $mtime1"
4641
4642                 cancel_lru_locks $OSC
4643                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4644         done
4645 }
4646 run_test 39g "write, chmod, stat ==============================="
4647
4648 # bug 11063
4649 test_39h() {
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651
4652         touch $DIR1/$tfile
4653         sleep 1
4654
4655         local d1=`date`
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4660         local d2=`date`
4661         if [ "$d1" != "$d2" ]; then
4662                 echo "write and touch not within one second"
4663         else
4664                 for (( i=0; i < 2; i++ )) ; do
4665                         local mtime2=`stat -c %Y $DIR1/$tfile`
4666                         [ "$mtime2" = $TEST_39_MTIME ] || \
4667                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4668
4669                         cancel_lru_locks $OSC
4670                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4671                 done
4672         fi
4673 }
4674 run_test 39h "write, utime within one second, stat ============="
4675
4676 test_39i() {
4677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4678
4679         touch $DIR1/$tfile
4680         sleep 1
4681
4682         echo hello >> $DIR1/$tfile
4683         local mtime1=`stat -c %Y $DIR1/$tfile`
4684
4685         mv $DIR1/$tfile $DIR1/$tfile-1
4686
4687         for (( i=0; i < 2; i++ )) ; do
4688                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4689
4690                 [ "$mtime1" = "$mtime2" ] || \
4691                         error "lost mtime: $mtime2, should be $mtime1"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39i "write, rename, stat =============================="
4698
4699 test_39j() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         start_full_debug_logging
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4707         lctl set_param fail_loc=0x80000412
4708         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4709                 error "multiop failed"
4710         local multipid=$!
4711         local mtime1=`stat -c %Y $DIR1/$tfile`
4712
4713         mv $DIR1/$tfile $DIR1/$tfile-1
4714
4715         kill -USR1 $multipid
4716         wait $multipid || error "multiop close failed"
4717
4718         for (( i=0; i < 2; i++ )) ; do
4719                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4720                 [ "$mtime1" = "$mtime2" ] ||
4721                         error "mtime is lost on close: $mtime2, " \
4722                               "should be $mtime1"
4723
4724                 cancel_lru_locks
4725                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4726         done
4727         lctl set_param fail_loc=0
4728         stop_full_debug_logging
4729 }
4730 run_test 39j "write, rename, close, stat ======================="
4731
4732 test_39k() {
4733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4734
4735         touch $DIR1/$tfile
4736         sleep 1
4737
4738         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4739         local multipid=$!
4740         local mtime1=`stat -c %Y $DIR1/$tfile`
4741
4742         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4743
4744         kill -USR1 $multipid
4745         wait $multipid || error "multiop close failed"
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749
4750                 [ "$mtime2" = $TEST_39_MTIME ] || \
4751                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4752
4753                 cancel_lru_locks
4754                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4755         done
4756 }
4757 run_test 39k "write, utime, close, stat ========================"
4758
4759 # this should be set to future
4760 TEST_39_ATIME=`date -d "1 year" +%s`
4761
4762 test_39l() {
4763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4764         remote_mds_nodsh && skip "remote MDS with nodsh"
4765
4766         local atime_diff=$(do_facet $SINGLEMDS \
4767                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4768         rm -rf $DIR/$tdir
4769         mkdir -p $DIR/$tdir
4770
4771         # test setting directory atime to future
4772         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4773         local atime=$(stat -c %X $DIR/$tdir)
4774         [ "$atime" = $TEST_39_ATIME ] ||
4775                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4776
4777         # test setting directory atime from future to now
4778         local now=$(date +%s)
4779         touch -a -d @$now $DIR/$tdir
4780
4781         atime=$(stat -c %X $DIR/$tdir)
4782         [ "$atime" -eq "$now"  ] ||
4783                 error "atime is not updated from future: $atime, $now"
4784
4785         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4786         sleep 3
4787
4788         # test setting directory atime when now > dir atime + atime_diff
4789         local d1=$(date +%s)
4790         ls $DIR/$tdir
4791         local d2=$(date +%s)
4792         cancel_lru_locks mdc
4793         atime=$(stat -c %X $DIR/$tdir)
4794         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4795                 error "atime is not updated  : $atime, should be $d2"
4796
4797         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4798         sleep 3
4799
4800         # test not setting directory atime when now < dir atime + atime_diff
4801         ls $DIR/$tdir
4802         cancel_lru_locks mdc
4803         atime=$(stat -c %X $DIR/$tdir)
4804         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4805                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4806
4807         do_facet $SINGLEMDS \
4808                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4809 }
4810 run_test 39l "directory atime update ==========================="
4811
4812 test_39m() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814
4815         touch $DIR1/$tfile
4816         sleep 2
4817         local far_past_mtime=$(date -d "May 29 1953" +%s)
4818         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4819
4820         touch -m -d @$far_past_mtime $DIR1/$tfile
4821         touch -a -d @$far_past_atime $DIR1/$tfile
4822
4823         for (( i=0; i < 2; i++ )) ; do
4824                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4825                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4826                         error "atime or mtime set incorrectly"
4827
4828                 cancel_lru_locks $OSC
4829                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4830         done
4831 }
4832 run_test 39m "test atime and mtime before 1970"
4833
4834 test_39n() { # LU-3832
4835         remote_mds_nodsh && skip "remote MDS with nodsh"
4836
4837         local atime_diff=$(do_facet $SINGLEMDS \
4838                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4839         local atime0
4840         local atime1
4841         local atime2
4842
4843         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4844
4845         rm -rf $DIR/$tfile
4846         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4847         atime0=$(stat -c %X $DIR/$tfile)
4848
4849         sleep 5
4850         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4851         atime1=$(stat -c %X $DIR/$tfile)
4852
4853         sleep 5
4854         cancel_lru_locks mdc
4855         cancel_lru_locks osc
4856         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4857         atime2=$(stat -c %X $DIR/$tfile)
4858
4859         do_facet $SINGLEMDS \
4860                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4861
4862         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4863         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4864 }
4865 run_test 39n "check that O_NOATIME is honored"
4866
4867 test_39o() {
4868         TESTDIR=$DIR/$tdir/$tfile
4869         [ -e $TESTDIR ] && rm -rf $TESTDIR
4870         mkdir -p $TESTDIR
4871         cd $TESTDIR
4872         links1=2
4873         ls
4874         mkdir a b
4875         ls
4876         links2=$(stat -c %h .)
4877         [ $(($links1 + 2)) != $links2 ] &&
4878                 error "wrong links count $(($links1 + 2)) != $links2"
4879         rmdir b
4880         links3=$(stat -c %h .)
4881         [ $(($links1 + 1)) != $links3 ] &&
4882                 error "wrong links count $links1 != $links3"
4883         return 0
4884 }
4885 run_test 39o "directory cached attributes updated after create"
4886
4887 test_39p() {
4888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4889
4890         local MDTIDX=1
4891         TESTDIR=$DIR/$tdir/$tdir
4892         [ -e $TESTDIR ] && rm -rf $TESTDIR
4893         test_mkdir -p $TESTDIR
4894         cd $TESTDIR
4895         links1=2
4896         ls
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4899         ls
4900         links2=$(stat -c %h .)
4901         [ $(($links1 + 2)) != $links2 ] &&
4902                 error "wrong links count $(($links1 + 2)) != $links2"
4903         rmdir remote_dir2
4904         links3=$(stat -c %h .)
4905         [ $(($links1 + 1)) != $links3 ] &&
4906                 error "wrong links count $links1 != $links3"
4907         return 0
4908 }
4909 run_test 39p "remote directory cached attributes updated after create ========"
4910
4911 test_39r() {
4912         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4913                 skip "no atime update on old OST"
4914         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4915                 skip_env "ldiskfs only test"
4916         fi
4917
4918         local saved_adiff
4919         saved_adiff=$(do_facet ost1 \
4920                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4921         stack_trap "do_facet ost1 \
4922                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4923
4924         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4925
4926         $LFS setstripe -i 0 $DIR/$tfile
4927         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4928                 error "can't write initial file"
4929         cancel_lru_locks osc
4930
4931         # exceed atime_diff and access file
4932         sleep 6
4933         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4934                 error "can't udpate atime"
4935
4936         local atime_cli=$(stat -c %X $DIR/$tfile)
4937         echo "client atime: $atime_cli"
4938         # allow atime update to be written to device
4939         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4940         sleep 5
4941
4942         local ostdev=$(ostdevname 1)
4943         local fid=($(lfs getstripe -y $DIR/$tfile |
4944                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4945         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4946         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4947
4948         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4949         local atime_ost=$(do_facet ost1 "$cmd" |&
4950                           awk -F'[: ]' '/atime:/ { print $4 }')
4951         (( atime_cli == atime_ost )) ||
4952                 error "atime on client $atime_cli != ost $atime_ost"
4953 }
4954 run_test 39r "lazy atime update on OST"
4955
4956 test_39q() { # LU-8041
4957         local testdir=$DIR/$tdir
4958         mkdir -p $testdir
4959         multiop_bg_pause $testdir D_c || error "multiop failed"
4960         local multipid=$!
4961         cancel_lru_locks mdc
4962         kill -USR1 $multipid
4963         local atime=$(stat -c %X $testdir)
4964         [ "$atime" -ne 0 ] || error "atime is zero"
4965 }
4966 run_test 39q "close won't zero out atime"
4967
4968 test_40() {
4969         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4970         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4971                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4972         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4973                 error "$tfile is not 4096 bytes in size"
4974 }
4975 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4976
4977 test_41() {
4978         # bug 1553
4979         small_write $DIR/f41 18
4980 }
4981 run_test 41 "test small file write + fstat ====================="
4982
4983 count_ost_writes() {
4984         lctl get_param -n ${OSC}.*.stats |
4985                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4986                         END { printf("%0.0f", writes) }'
4987 }
4988
4989 # decent default
4990 WRITEBACK_SAVE=500
4991 DIRTY_RATIO_SAVE=40
4992 MAX_DIRTY_RATIO=50
4993 BG_DIRTY_RATIO_SAVE=10
4994 MAX_BG_DIRTY_RATIO=25
4995
4996 start_writeback() {
4997         trap 0
4998         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4999         # dirty_ratio, dirty_background_ratio
5000         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5001                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5002                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5003                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5004         else
5005                 # if file not here, we are a 2.4 kernel
5006                 kill -CONT `pidof kupdated`
5007         fi
5008 }
5009
5010 stop_writeback() {
5011         # setup the trap first, so someone cannot exit the test at the
5012         # exact wrong time and mess up a machine
5013         trap start_writeback EXIT
5014         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5015         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5016                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 # save and increase /proc/sys/vm/dirty_ratio
5020                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5021                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5022                 # save and increase /proc/sys/vm/dirty_background_ratio
5023                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5024                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5025         else
5026                 # if file not here, we are a 2.4 kernel
5027                 kill -STOP `pidof kupdated`
5028         fi
5029 }
5030
5031 # ensure that all stripes have some grant before we test client-side cache
5032 setup_test42() {
5033         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5034                 dd if=/dev/zero of=$i bs=4k count=1
5035                 rm $i
5036         done
5037 }
5038
5039 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5040 # file truncation, and file removal.
5041 test_42a() {
5042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5043
5044         setup_test42
5045         cancel_lru_locks $OSC
5046         stop_writeback
5047         sync; sleep 1; sync # just to be safe
5048         BEFOREWRITES=`count_ost_writes`
5049         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5050         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5051         AFTERWRITES=`count_ost_writes`
5052         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5053                 error "$BEFOREWRITES < $AFTERWRITES"
5054         start_writeback
5055 }
5056 run_test 42a "ensure that we don't flush on close"
5057
5058 test_42b() {
5059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5060
5061         setup_test42
5062         cancel_lru_locks $OSC
5063         stop_writeback
5064         sync
5065         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5066         BEFOREWRITES=$(count_ost_writes)
5067         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5068         AFTERWRITES=$(count_ost_writes)
5069         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5070                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5071         fi
5072         BEFOREWRITES=$(count_ost_writes)
5073         sync || error "sync: $?"
5074         AFTERWRITES=$(count_ost_writes)
5075         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5076                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5077         fi
5078         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5079         start_writeback
5080         return 0
5081 }
5082 run_test 42b "test destroy of file with cached dirty data ======"
5083
5084 # if these tests just want to test the effect of truncation,
5085 # they have to be very careful.  consider:
5086 # - the first open gets a {0,EOF}PR lock
5087 # - the first write conflicts and gets a {0, count-1}PW
5088 # - the rest of the writes are under {count,EOF}PW
5089 # - the open for truncate tries to match a {0,EOF}PR
5090 #   for the filesize and cancels the PWs.
5091 # any number of fixes (don't get {0,EOF} on open, match
5092 # composite locks, do smarter file size management) fix
5093 # this, but for now we want these tests to verify that
5094 # the cancellation with truncate intent works, so we
5095 # start the file with a full-file pw lock to match against
5096 # until the truncate.
5097 trunc_test() {
5098         test=$1
5099         file=$DIR/$test
5100         offset=$2
5101         cancel_lru_locks $OSC
5102         stop_writeback
5103         # prime the file with 0,EOF PW to match
5104         touch $file
5105         $TRUNCATE $file 0
5106         sync; sync
5107         # now the real test..
5108         dd if=/dev/zero of=$file bs=1024 count=100
5109         BEFOREWRITES=`count_ost_writes`
5110         $TRUNCATE $file $offset
5111         cancel_lru_locks $OSC
5112         AFTERWRITES=`count_ost_writes`
5113         start_writeback
5114 }
5115
5116 test_42c() {
5117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5118
5119         trunc_test 42c 1024
5120         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5121                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5122         rm $file
5123 }
5124 run_test 42c "test partial truncate of file with cached dirty data"
5125
5126 test_42d() {
5127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5128
5129         trunc_test 42d 0
5130         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5131                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5132         rm $file
5133 }
5134 run_test 42d "test complete truncate of file with cached dirty data"
5135
5136 test_42e() { # bug22074
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         local TDIR=$DIR/${tdir}e
5140         local pages=16 # hardcoded 16 pages, don't change it.
5141         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5142         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5143         local max_dirty_mb
5144         local warmup_files
5145
5146         test_mkdir $DIR/${tdir}e
5147         $LFS setstripe -c 1 $TDIR
5148         createmany -o $TDIR/f $files
5149
5150         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5151
5152         # we assume that with $OSTCOUNT files, at least one of them will
5153         # be allocated on OST0.
5154         warmup_files=$((OSTCOUNT * max_dirty_mb))
5155         createmany -o $TDIR/w $warmup_files
5156
5157         # write a large amount of data into one file and sync, to get good
5158         # avail_grant number from OST.
5159         for ((i=0; i<$warmup_files; i++)); do
5160                 idx=$($LFS getstripe -i $TDIR/w$i)
5161                 [ $idx -ne 0 ] && continue
5162                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5163                 break
5164         done
5165         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5166         sync
5167         $LCTL get_param $proc_osc0/cur_dirty_bytes
5168         $LCTL get_param $proc_osc0/cur_grant_bytes
5169
5170         # create as much dirty pages as we can while not to trigger the actual
5171         # RPCs directly. but depends on the env, VFS may trigger flush during this
5172         # period, hopefully we are good.
5173         for ((i=0; i<$warmup_files; i++)); do
5174                 idx=$($LFS getstripe -i $TDIR/w$i)
5175                 [ $idx -ne 0 ] && continue
5176                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5177         done
5178         $LCTL get_param $proc_osc0/cur_dirty_bytes
5179         $LCTL get_param $proc_osc0/cur_grant_bytes
5180
5181         # perform the real test
5182         $LCTL set_param $proc_osc0/rpc_stats 0
5183         for ((;i<$files; i++)); do
5184                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5185                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5186         done
5187         sync
5188         $LCTL get_param $proc_osc0/rpc_stats
5189
5190         local percent=0
5191         local have_ppr=false
5192         $LCTL get_param $proc_osc0/rpc_stats |
5193                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5194                         # skip lines until we are at the RPC histogram data
5195                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5196                         $have_ppr || continue
5197
5198                         # we only want the percent stat for < 16 pages
5199                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5200
5201                         percent=$((percent + WPCT))
5202                         if [[ $percent -gt 15 ]]; then
5203                                 error "less than 16-pages write RPCs" \
5204                                       "$percent% > 15%"
5205                                 break
5206                         fi
5207                 done
5208         rm -rf $TDIR
5209 }
5210 run_test 42e "verify sub-RPC writes are not done synchronously"
5211
5212 test_43A() { # was test_43
5213         test_mkdir $DIR/$tdir
5214         cp -p /bin/ls $DIR/$tdir/$tfile
5215         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5216         pid=$!
5217         # give multiop a chance to open
5218         sleep 1
5219
5220         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5221         kill -USR1 $pid
5222         # Wait for multiop to exit
5223         wait $pid
5224 }
5225 run_test 43A "execution of file opened for write should return -ETXTBSY"
5226
5227 test_43a() {
5228         test_mkdir $DIR/$tdir
5229         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5230         $DIR/$tdir/sleep 60 &
5231         SLEEP_PID=$!
5232         # Make sure exec of $tdir/sleep wins race with truncate
5233         sleep 1
5234         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5235         kill $SLEEP_PID
5236 }
5237 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5238
5239 test_43b() {
5240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5241
5242         test_mkdir $DIR/$tdir
5243         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5244         $DIR/$tdir/sleep 60 &
5245         SLEEP_PID=$!
5246         # Make sure exec of $tdir/sleep wins race with truncate
5247         sleep 1
5248         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5249         kill $SLEEP_PID
5250 }
5251 run_test 43b "truncate of file being executed should return -ETXTBSY"
5252
5253 test_43c() {
5254         local testdir="$DIR/$tdir"
5255         test_mkdir $testdir
5256         cp $SHELL $testdir/
5257         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5258                 ( cd $testdir && md5sum -c )
5259 }
5260 run_test 43c "md5sum of copy into lustre"
5261
5262 test_44A() { # was test_44
5263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5264
5265         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5266         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5267 }
5268 run_test 44A "zero length read from a sparse stripe"
5269
5270 test_44a() {
5271         local nstripe=$($LFS getstripe -c -d $DIR)
5272         [ -z "$nstripe" ] && skip "can't get stripe info"
5273         [[ $nstripe -gt $OSTCOUNT ]] &&
5274                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5275
5276         local stride=$($LFS getstripe -S -d $DIR)
5277         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5278                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5279         fi
5280
5281         OFFSETS="0 $((stride/2)) $((stride-1))"
5282         for offset in $OFFSETS; do
5283                 for i in $(seq 0 $((nstripe-1))); do
5284                         local GLOBALOFFSETS=""
5285                         # size in Bytes
5286                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5287                         local myfn=$DIR/d44a-$size
5288                         echo "--------writing $myfn at $size"
5289                         ll_sparseness_write $myfn $size ||
5290                                 error "ll_sparseness_write"
5291                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5292                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5293                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5294
5295                         for j in $(seq 0 $((nstripe-1))); do
5296                                 # size in Bytes
5297                                 size=$((((j + $nstripe )*$stride + $offset)))
5298                                 ll_sparseness_write $myfn $size ||
5299                                         error "ll_sparseness_write"
5300                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5301                         done
5302                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5303                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5304                         rm -f $myfn
5305                 done
5306         done
5307 }
5308 run_test 44a "test sparse pwrite ==============================="
5309
5310 dirty_osc_total() {
5311         tot=0
5312         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5313                 tot=$(($tot + $d))
5314         done
5315         echo $tot
5316 }
5317 do_dirty_record() {
5318         before=`dirty_osc_total`
5319         echo executing "\"$*\""
5320         eval $*
5321         after=`dirty_osc_total`
5322         echo before $before, after $after
5323 }
5324 test_45() {
5325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5326
5327         f="$DIR/f45"
5328         # Obtain grants from OST if it supports it
5329         echo blah > ${f}_grant
5330         stop_writeback
5331         sync
5332         do_dirty_record "echo blah > $f"
5333         [[ $before -eq $after ]] && error "write wasn't cached"
5334         do_dirty_record "> $f"
5335         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5336         do_dirty_record "echo blah > $f"
5337         [[ $before -eq $after ]] && error "write wasn't cached"
5338         do_dirty_record "sync"
5339         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5340         do_dirty_record "echo blah > $f"
5341         [[ $before -eq $after ]] && error "write wasn't cached"
5342         do_dirty_record "cancel_lru_locks osc"
5343         [[ $before -gt $after ]] ||
5344                 error "lock cancellation didn't lower dirty count"
5345         start_writeback
5346 }
5347 run_test 45 "osc io page accounting ============================"
5348
5349 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5350 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5351 # objects offset and an assert hit when an rpc was built with 1023's mapped
5352 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5353 test_46() {
5354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5355
5356         f="$DIR/f46"
5357         stop_writeback
5358         sync
5359         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5360         sync
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5363         sync
5364         start_writeback
5365 }
5366 run_test 46 "dirtying a previously written page ================"
5367
5368 # test_47 is removed "Device nodes check" is moved to test_28
5369
5370 test_48a() { # bug 2399
5371         [ "$mds1_FSTYPE" = "zfs" ] &&
5372         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5373                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5374
5375         test_mkdir $DIR/$tdir
5376         cd $DIR/$tdir
5377         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5378         test_mkdir $DIR/$tdir
5379         touch foo || error "'touch foo' failed after recreating cwd"
5380         test_mkdir bar
5381         touch .foo || error "'touch .foo' failed after recreating cwd"
5382         test_mkdir .bar
5383         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5384         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5385         cd . || error "'cd .' failed after recreating cwd"
5386         mkdir . && error "'mkdir .' worked after recreating cwd"
5387         rmdir . && error "'rmdir .' worked after recreating cwd"
5388         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5389         cd .. || error "'cd ..' failed after recreating cwd"
5390 }
5391 run_test 48a "Access renamed working dir (should return errors)="
5392
5393 test_48b() { # bug 2399
5394         rm -rf $DIR/$tdir
5395         test_mkdir $DIR/$tdir
5396         cd $DIR/$tdir
5397         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5398         touch foo && error "'touch foo' worked after removing cwd"
5399         mkdir foo && error "'mkdir foo' worked after removing cwd"
5400         touch .foo && error "'touch .foo' worked after removing cwd"
5401         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5402         ls . > /dev/null && error "'ls .' worked after removing cwd"
5403         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5404         mkdir . && error "'mkdir .' worked after removing cwd"
5405         rmdir . && error "'rmdir .' worked after removing cwd"
5406         ln -s . foo && error "'ln -s .' worked after removing cwd"
5407         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5408 }
5409 run_test 48b "Access removed working dir (should return errors)="
5410
5411 test_48c() { # bug 2350
5412         #lctl set_param debug=-1
5413         #set -vx
5414         rm -rf $DIR/$tdir
5415         test_mkdir -p $DIR/$tdir/dir
5416         cd $DIR/$tdir/dir
5417         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5418         $TRACE touch foo && error "touch foo worked after removing cwd"
5419         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5420         touch .foo && error "touch .foo worked after removing cwd"
5421         mkdir .foo && error "mkdir .foo worked after removing cwd"
5422         $TRACE ls . && error "'ls .' worked after removing cwd"
5423         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5424         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5425         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5426         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5427         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5428 }
5429 run_test 48c "Access removed working subdir (should return errors)"
5430
5431 test_48d() { # bug 2350
5432         #lctl set_param debug=-1
5433         #set -vx
5434         rm -rf $DIR/$tdir
5435         test_mkdir -p $DIR/$tdir/dir
5436         cd $DIR/$tdir/dir
5437         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5438         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5439         $TRACE touch foo && error "'touch foo' worked after removing parent"
5440         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5441         touch .foo && error "'touch .foo' worked after removing parent"
5442         mkdir .foo && error "mkdir .foo worked after removing parent"
5443         $TRACE ls . && error "'ls .' worked after removing parent"
5444         $TRACE ls .. && error "'ls ..' worked after removing parent"
5445         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5446         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5447         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5448         true
5449 }
5450 run_test 48d "Access removed parent subdir (should return errors)"
5451
5452 test_48e() { # bug 4134
5453         #lctl set_param debug=-1
5454         #set -vx
5455         rm -rf $DIR/$tdir
5456         test_mkdir -p $DIR/$tdir/dir
5457         cd $DIR/$tdir/dir
5458         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5459         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5460         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5461         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5462         # On a buggy kernel addition of "touch foo" after cd .. will
5463         # produce kernel oops in lookup_hash_it
5464         touch ../foo && error "'cd ..' worked after recreate parent"
5465         cd $DIR
5466         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5467 }
5468 run_test 48e "Access to recreated parent subdir (should return errors)"
5469
5470 test_48f() {
5471         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5472                 skip "need MDS >= 2.13.55"
5473         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5474         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5475                 skip "needs different host for mdt1 mdt2"
5476         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5477
5478         $LFS mkdir -i0 $DIR/$tdir
5479         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5480
5481         for d in sub1 sub2 sub3; do
5482                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5483                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5484                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5485         done
5486
5487         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5488 }
5489 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5490
5491 test_49() { # LU-1030
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493         remote_ost_nodsh && skip "remote OST with nodsh"
5494
5495         # get ost1 size - $FSNAME-OST0000
5496         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5497                 awk '{ print $4 }')
5498         # write 800M at maximum
5499         [[ $ost1_size -lt 2 ]] && ost1_size=2
5500         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5501
5502         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5503         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5504         local dd_pid=$!
5505
5506         # change max_pages_per_rpc while writing the file
5507         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5508         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5509         # loop until dd process exits
5510         while ps ax -opid | grep -wq $dd_pid; do
5511                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5512                 sleep $((RANDOM % 5 + 1))
5513         done
5514         # restore original max_pages_per_rpc
5515         $LCTL set_param $osc1_mppc=$orig_mppc
5516         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5517 }
5518 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5519
5520 test_50() {
5521         # bug 1485
5522         test_mkdir $DIR/$tdir
5523         cd $DIR/$tdir
5524         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5525 }
5526 run_test 50 "special situations: /proc symlinks  ==============="
5527
5528 test_51a() {    # was test_51
5529         # bug 1516 - create an empty entry right after ".." then split dir
5530         test_mkdir -c1 $DIR/$tdir
5531         touch $DIR/$tdir/foo
5532         $MCREATE $DIR/$tdir/bar
5533         rm $DIR/$tdir/foo
5534         createmany -m $DIR/$tdir/longfile 201
5535         FNUM=202
5536         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5537                 $MCREATE $DIR/$tdir/longfile$FNUM
5538                 FNUM=$(($FNUM + 1))
5539                 echo -n "+"
5540         done
5541         echo
5542         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5543 }
5544 run_test 51a "special situations: split htree with empty entry =="
5545
5546 cleanup_print_lfs_df () {
5547         trap 0
5548         $LFS df
5549         $LFS df -i
5550 }
5551
5552 test_51b() {
5553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5554
5555         local dir=$DIR/$tdir
5556         local nrdirs=$((65536 + 100))
5557
5558         # cleanup the directory
5559         rm -fr $dir
5560
5561         test_mkdir -c1 $dir
5562
5563         $LFS df
5564         $LFS df -i
5565         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5566         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5567         [[ $numfree -lt $nrdirs ]] &&
5568                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5569
5570         # need to check free space for the directories as well
5571         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5572         numfree=$(( blkfree / $(fs_inode_ksize) ))
5573         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5574
5575         trap cleanup_print_lfs_df EXIT
5576
5577         # create files
5578         createmany -d $dir/d $nrdirs || {
5579                 unlinkmany $dir/d $nrdirs
5580                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5581         }
5582
5583         # really created :
5584         nrdirs=$(ls -U $dir | wc -l)
5585
5586         # unlink all but 100 subdirectories, then check it still works
5587         local left=100
5588         local delete=$((nrdirs - left))
5589
5590         $LFS df
5591         $LFS df -i
5592
5593         # for ldiskfs the nlink count should be 1, but this is OSD specific
5594         # and so this is listed for informational purposes only
5595         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5596         unlinkmany -d $dir/d $delete ||
5597                 error "unlink of first $delete subdirs failed"
5598
5599         echo "nlink between: $(stat -c %h $dir)"
5600         local found=$(ls -U $dir | wc -l)
5601         [ $found -ne $left ] &&
5602                 error "can't find subdirs: found only $found, expected $left"
5603
5604         unlinkmany -d $dir/d $delete $left ||
5605                 error "unlink of second $left subdirs failed"
5606         # regardless of whether the backing filesystem tracks nlink accurately
5607         # or not, the nlink count shouldn't be more than "." and ".." here
5608         local after=$(stat -c %h $dir)
5609         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5610                 echo "nlink after: $after"
5611
5612         cleanup_print_lfs_df
5613 }
5614 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5615
5616 test_51d() {
5617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5618         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5619
5620         test_mkdir $DIR/$tdir
5621         createmany -o $DIR/$tdir/t- 1000
5622         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5623         for N in $(seq 0 $((OSTCOUNT - 1))); do
5624                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5625                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5626                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5627                         '($1 == '$N') { objs += 1 } \
5628                         END { printf("%0.0f", objs) }')
5629                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5630         done
5631         unlinkmany $DIR/$tdir/t- 1000
5632
5633         NLAST=0
5634         for N in $(seq 1 $((OSTCOUNT - 1))); do
5635                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5636                         error "OST $N has less objects vs OST $NLAST" \
5637                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5638                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5639                         error "OST $N has less objects vs OST $NLAST" \
5640                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5641
5642                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5643                         error "OST $N has less #0 objects vs OST $NLAST" \
5644                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5645                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5646                         error "OST $N has less #0 objects vs OST $NLAST" \
5647                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5648                 NLAST=$N
5649         done
5650         rm -f $TMP/$tfile
5651 }
5652 run_test 51d "check object distribution"
5653
5654 test_51e() {
5655         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5656                 skip_env "ldiskfs only test"
5657         fi
5658
5659         test_mkdir -c1 $DIR/$tdir
5660         test_mkdir -c1 $DIR/$tdir/d0
5661
5662         touch $DIR/$tdir/d0/foo
5663         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5664                 error "file exceed 65000 nlink limit!"
5665         unlinkmany $DIR/$tdir/d0/f- 65001
5666         return 0
5667 }
5668 run_test 51e "check file nlink limit"
5669
5670 test_51f() {
5671         test_mkdir $DIR/$tdir
5672
5673         local max=100000
5674         local ulimit_old=$(ulimit -n)
5675         local spare=20 # number of spare fd's for scripts/libraries, etc.
5676         local mdt=$($LFS getstripe -m $DIR/$tdir)
5677         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5678
5679         echo "MDT$mdt numfree=$numfree, max=$max"
5680         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5681         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5682                 while ! ulimit -n $((numfree + spare)); do
5683                         numfree=$((numfree * 3 / 4))
5684                 done
5685                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5686         else
5687                 echo "left ulimit at $ulimit_old"
5688         fi
5689
5690         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5691                 unlinkmany $DIR/$tdir/f $numfree
5692                 error "create+open $numfree files in $DIR/$tdir failed"
5693         }
5694         ulimit -n $ulimit_old
5695
5696         # if createmany exits at 120s there will be fewer than $numfree files
5697         unlinkmany $DIR/$tdir/f $numfree || true
5698 }
5699 run_test 51f "check many open files limit"
5700
5701 test_52a() {
5702         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5703         test_mkdir $DIR/$tdir
5704         touch $DIR/$tdir/foo
5705         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5706         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5707         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5708         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5709         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5710                                         error "link worked"
5711         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5712         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5713         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5714                                                      error "lsattr"
5715         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5716         cp -r $DIR/$tdir $TMP/
5717         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5718 }
5719 run_test 52a "append-only flag test (should return errors)"
5720
5721 test_52b() {
5722         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5723         test_mkdir $DIR/$tdir
5724         touch $DIR/$tdir/foo
5725         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5726         cat test > $DIR/$tdir/foo && error "cat test worked"
5727         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5728         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5729         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5730                                         error "link worked"
5731         echo foo >> $DIR/$tdir/foo && error "echo worked"
5732         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5733         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5734         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5735         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5736                                                         error "lsattr"
5737         chattr -i $DIR/$tdir/foo || error "chattr failed"
5738
5739         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5740 }
5741 run_test 52b "immutable flag test (should return errors) ======="
5742
5743 test_53() {
5744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5745         remote_mds_nodsh && skip "remote MDS with nodsh"
5746         remote_ost_nodsh && skip "remote OST with nodsh"
5747
5748         local param
5749         local param_seq
5750         local ostname
5751         local mds_last
5752         local mds_last_seq
5753         local ost_last
5754         local ost_last_seq
5755         local ost_last_id
5756         local ostnum
5757         local node
5758         local found=false
5759         local support_last_seq=true
5760
5761         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5762                 support_last_seq=false
5763
5764         # only test MDT0000
5765         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5766         local value
5767         for value in $(do_facet $SINGLEMDS \
5768                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5769                 param=$(echo ${value[0]} | cut -d "=" -f1)
5770                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5771
5772                 if $support_last_seq; then
5773                         param_seq=$(echo $param |
5774                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5775                         mds_last_seq=$(do_facet $SINGLEMDS \
5776                                        $LCTL get_param -n $param_seq)
5777                 fi
5778                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5779
5780                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5781                 node=$(facet_active_host ost$((ostnum+1)))
5782                 param="obdfilter.$ostname.last_id"
5783                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5784                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5785                         ost_last_id=$ost_last
5786
5787                         if $support_last_seq; then
5788                                 ost_last_id=$(echo $ost_last |
5789                                               awk -F':' '{print $2}' |
5790                                               sed -e "s/^0x//g")
5791                                 ost_last_seq=$(echo $ost_last |
5792                                                awk -F':' '{print $1}')
5793                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5794                         fi
5795
5796                         if [[ $ost_last_id != $mds_last ]]; then
5797                                 error "$ost_last_id != $mds_last"
5798                         else
5799                                 found=true
5800                                 break
5801                         fi
5802                 done
5803         done
5804         $found || error "can not match last_seq/last_id for $mdtosc"
5805         return 0
5806 }
5807 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5808
5809 test_54a() {
5810         perl -MSocket -e ';' || skip "no Socket perl module installed"
5811
5812         $SOCKETSERVER $DIR/socket ||
5813                 error "$SOCKETSERVER $DIR/socket failed: $?"
5814         $SOCKETCLIENT $DIR/socket ||
5815                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5816         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5817 }
5818 run_test 54a "unix domain socket test =========================="
5819
5820 test_54b() {
5821         f="$DIR/f54b"
5822         mknod $f c 1 3
5823         chmod 0666 $f
5824         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5825 }
5826 run_test 54b "char device works in lustre ======================"
5827
5828 find_loop_dev() {
5829         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5830         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5831         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5832
5833         for i in $(seq 3 7); do
5834                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5835                 LOOPDEV=$LOOPBASE$i
5836                 LOOPNUM=$i
5837                 break
5838         done
5839 }
5840
5841 cleanup_54c() {
5842         local rc=0
5843         loopdev="$DIR/loop54c"
5844
5845         trap 0
5846         $UMOUNT $DIR/$tdir || rc=$?
5847         losetup -d $loopdev || true
5848         losetup -d $LOOPDEV || true
5849         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5850         return $rc
5851 }
5852
5853 test_54c() {
5854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5855
5856         loopdev="$DIR/loop54c"
5857
5858         find_loop_dev
5859         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5860         trap cleanup_54c EXIT
5861         mknod $loopdev b 7 $LOOPNUM
5862         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5863         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5864         losetup $loopdev $DIR/$tfile ||
5865                 error "can't set up $loopdev for $DIR/$tfile"
5866         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5867         test_mkdir $DIR/$tdir
5868         mount -t ext2 $loopdev $DIR/$tdir ||
5869                 error "error mounting $loopdev on $DIR/$tdir"
5870         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5871                 error "dd write"
5872         df $DIR/$tdir
5873         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5874                 error "dd read"
5875         cleanup_54c
5876 }
5877 run_test 54c "block device works in lustre ====================="
5878
5879 test_54d() {
5880         f="$DIR/f54d"
5881         string="aaaaaa"
5882         mknod $f p
5883         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5884 }
5885 run_test 54d "fifo device works in lustre ======================"
5886
5887 test_54e() {
5888         f="$DIR/f54e"
5889         string="aaaaaa"
5890         cp -aL /dev/console $f
5891         echo $string > $f || error "echo $string to $f failed"
5892 }
5893 run_test 54e "console/tty device works in lustre ======================"
5894
5895 test_56a() {
5896         local numfiles=3
5897         local numdirs=2
5898         local dir=$DIR/$tdir
5899
5900         rm -rf $dir
5901         test_mkdir -p $dir/dir
5902         for i in $(seq $numfiles); do
5903                 touch $dir/file$i
5904                 touch $dir/dir/file$i
5905         done
5906
5907         local numcomp=$($LFS getstripe --component-count $dir)
5908
5909         [[ $numcomp == 0 ]] && numcomp=1
5910
5911         # test lfs getstripe with --recursive
5912         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5913
5914         [[ $filenum -eq $((numfiles * 2)) ]] ||
5915                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5916         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5917         [[ $filenum -eq $numfiles ]] ||
5918                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5919         echo "$LFS getstripe showed obdidx or l_ost_idx"
5920
5921         # test lfs getstripe with file instead of dir
5922         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5923         [[ $filenum -eq 1 ]] ||
5924                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5925         echo "$LFS getstripe file1 passed"
5926
5927         #test lfs getstripe with --verbose
5928         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5929         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5930                 error "$LFS getstripe --verbose $dir: "\
5931                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5932         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5933                 error "$LFS getstripe $dir: showed lmm_magic"
5934
5935         #test lfs getstripe with -v prints lmm_fid
5936         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5937         local countfids=$((numdirs + numfiles * numcomp))
5938         [[ $filenum -eq $countfids ]] ||
5939                 error "$LFS getstripe -v $dir: "\
5940                       "got $filenum want $countfids lmm_fid"
5941         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5942                 error "$LFS getstripe $dir: showed lmm_fid by default"
5943         echo "$LFS getstripe --verbose passed"
5944
5945         #check for FID information
5946         local fid1=$($LFS getstripe --fid $dir/file1)
5947         local fid2=$($LFS getstripe --verbose $dir/file1 |
5948                      awk '/lmm_fid: / { print $2; exit; }')
5949         local fid3=$($LFS path2fid $dir/file1)
5950
5951         [ "$fid1" != "$fid2" ] &&
5952                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5953         [ "$fid1" != "$fid3" ] &&
5954                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5955         echo "$LFS getstripe --fid passed"
5956
5957         #test lfs getstripe with --obd
5958         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5959                 error "$LFS getstripe --obd wrong_uuid: should return error"
5960
5961         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5962
5963         local ostidx=1
5964         local obduuid=$(ostuuid_from_index $ostidx)
5965         local found=$($LFS getstripe -r --obd $obduuid $dir |
5966                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5967
5968         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5969         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5970                 ((filenum--))
5971         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5972                 ((filenum--))
5973
5974         [[ $found -eq $filenum ]] ||
5975                 error "$LFS getstripe --obd: found $found expect $filenum"
5976         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5977                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5978                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5979                 error "$LFS getstripe --obd: should not show file on other obd"
5980         echo "$LFS getstripe --obd passed"
5981 }
5982 run_test 56a "check $LFS getstripe"
5983
5984 test_56b() {
5985         local dir=$DIR/$tdir
5986         local numdirs=3
5987
5988         test_mkdir $dir
5989         for i in $(seq $numdirs); do
5990                 test_mkdir $dir/dir$i
5991         done
5992
5993         # test lfs getdirstripe default mode is non-recursion, which is
5994         # different from lfs getstripe
5995         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5996
5997         [[ $dircnt -eq 1 ]] ||
5998                 error "$LFS getdirstripe: found $dircnt, not 1"
5999         dircnt=$($LFS getdirstripe --recursive $dir |
6000                 grep -c lmv_stripe_count)
6001         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6002                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6003 }
6004 run_test 56b "check $LFS getdirstripe"
6005
6006 test_56c() {
6007         remote_ost_nodsh && skip "remote OST with nodsh"
6008
6009         local ost_idx=0
6010         local ost_name=$(ostname_from_index $ost_idx)
6011         local old_status=$(ost_dev_status $ost_idx)
6012         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6013
6014         [[ -z "$old_status" ]] ||
6015                 skip_env "OST $ost_name is in $old_status status"
6016
6017         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6018         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6019                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6020         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6021                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6022                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6023         fi
6024
6025         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6026                 error "$LFS df -v showing inactive devices"
6027         sleep_maxage
6028
6029         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6030
6031         [[ "$new_status" =~ "D" ]] ||
6032                 error "$ost_name status is '$new_status', missing 'D'"
6033         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6034                 [[ "$new_status" =~ "N" ]] ||
6035                         error "$ost_name status is '$new_status', missing 'N'"
6036         fi
6037         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6038                 [[ "$new_status" =~ "f" ]] ||
6039                         error "$ost_name status is '$new_status', missing 'f'"
6040         fi
6041
6042         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6043         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6044                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6045         [[ -z "$p" ]] && restore_lustre_params < $p || true
6046         sleep_maxage
6047
6048         new_status=$(ost_dev_status $ost_idx)
6049         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6050                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6051         # can't check 'f' as devices may actually be on flash
6052 }
6053 run_test 56c "check 'lfs df' showing device status"
6054
6055 test_56d() {
6056         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6057         local osts=$($LFS df -v $MOUNT | grep -c OST)
6058
6059         $LFS df $MOUNT
6060
6061         (( mdts == MDSCOUNT )) ||
6062                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6063         (( osts == OSTCOUNT )) ||
6064                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6065 }
6066 run_test 56d "'lfs df -v' prints only configured devices"
6067
6068 NUMFILES=3
6069 NUMDIRS=3
6070 setup_56() {
6071         local local_tdir="$1"
6072         local local_numfiles="$2"
6073         local local_numdirs="$3"
6074         local dir_params="$4"
6075         local dir_stripe_params="$5"
6076
6077         if [ ! -d "$local_tdir" ] ; then
6078                 test_mkdir -p $dir_stripe_params $local_tdir
6079                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6080                 for i in $(seq $local_numfiles) ; do
6081                         touch $local_tdir/file$i
6082                 done
6083                 for i in $(seq $local_numdirs) ; do
6084                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6085                         for j in $(seq $local_numfiles) ; do
6086                                 touch $local_tdir/dir$i/file$j
6087                         done
6088                 done
6089         fi
6090 }
6091
6092 setup_56_special() {
6093         local local_tdir=$1
6094         local local_numfiles=$2
6095         local local_numdirs=$3
6096
6097         setup_56 $local_tdir $local_numfiles $local_numdirs
6098
6099         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6100                 for i in $(seq $local_numfiles) ; do
6101                         mknod $local_tdir/loop${i}b b 7 $i
6102                         mknod $local_tdir/null${i}c c 1 3
6103                         ln -s $local_tdir/file1 $local_tdir/link${i}
6104                 done
6105                 for i in $(seq $local_numdirs) ; do
6106                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6107                         mknod $local_tdir/dir$i/null${i}c c 1 3
6108                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6109                 done
6110         fi
6111 }
6112
6113 test_56g() {
6114         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6115         local expected=$(($NUMDIRS + 2))
6116
6117         setup_56 $dir $NUMFILES $NUMDIRS
6118
6119         # test lfs find with -name
6120         for i in $(seq $NUMFILES) ; do
6121                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6122
6123                 [ $nums -eq $expected ] ||
6124                         error "lfs find -name '*$i' $dir wrong: "\
6125                               "found $nums, expected $expected"
6126         done
6127 }
6128 run_test 56g "check lfs find -name"
6129
6130 test_56h() {
6131         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6132         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6133
6134         setup_56 $dir $NUMFILES $NUMDIRS
6135
6136         # test lfs find with ! -name
6137         for i in $(seq $NUMFILES) ; do
6138                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6139
6140                 [ $nums -eq $expected ] ||
6141                         error "lfs find ! -name '*$i' $dir wrong: "\
6142                               "found $nums, expected $expected"
6143         done
6144 }
6145 run_test 56h "check lfs find ! -name"
6146
6147 test_56i() {
6148         local dir=$DIR/$tdir
6149
6150         test_mkdir $dir
6151
6152         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6153         local out=$($cmd)
6154
6155         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6156 }
6157 run_test 56i "check 'lfs find -ost UUID' skips directories"
6158
6159 test_56j() {
6160         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6161
6162         setup_56_special $dir $NUMFILES $NUMDIRS
6163
6164         local expected=$((NUMDIRS + 1))
6165         local cmd="$LFS find -type d $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170 }
6171 run_test 56j "check lfs find -type d"
6172
6173 test_56k() {
6174         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6175
6176         setup_56_special $dir $NUMFILES $NUMDIRS
6177
6178         local expected=$(((NUMDIRS + 1) * NUMFILES))
6179         local cmd="$LFS find -type f $dir"
6180         local nums=$($cmd | wc -l)
6181
6182         [ $nums -eq $expected ] ||
6183                 error "'$cmd' wrong: found $nums, expected $expected"
6184 }
6185 run_test 56k "check lfs find -type f"
6186
6187 test_56l() {
6188         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6189
6190         setup_56_special $dir $NUMFILES $NUMDIRS
6191
6192         local expected=$((NUMDIRS + NUMFILES))
6193         local cmd="$LFS find -type b $dir"
6194         local nums=$($cmd | wc -l)
6195
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198 }
6199 run_test 56l "check lfs find -type b"
6200
6201 test_56m() {
6202         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6203
6204         setup_56_special $dir $NUMFILES $NUMDIRS
6205
6206         local expected=$((NUMDIRS + NUMFILES))
6207         local cmd="$LFS find -type c $dir"
6208         local nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211 }
6212 run_test 56m "check lfs find -type c"
6213
6214 test_56n() {
6215         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6216         setup_56_special $dir $NUMFILES $NUMDIRS
6217
6218         local expected=$((NUMDIRS + NUMFILES))
6219         local cmd="$LFS find -type l $dir"
6220         local nums=$($cmd | wc -l)
6221
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224 }
6225 run_test 56n "check lfs find -type l"
6226
6227 test_56o() {
6228         local dir=$DIR/$tdir
6229
6230         setup_56 $dir $NUMFILES $NUMDIRS
6231         utime $dir/file1 > /dev/null || error "utime (1)"
6232         utime $dir/file2 > /dev/null || error "utime (2)"
6233         utime $dir/dir1 > /dev/null || error "utime (3)"
6234         utime $dir/dir2 > /dev/null || error "utime (4)"
6235         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6236         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6237
6238         local expected=4
6239         local nums=$($LFS find -mtime +0 $dir | wc -l)
6240
6241         [ $nums -eq $expected ] ||
6242                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6243
6244         expected=12
6245         cmd="$LFS find -mtime 0 $dir"
6246         nums=$($cmd | wc -l)
6247         [ $nums -eq $expected ] ||
6248                 error "'$cmd' wrong: found $nums, expected $expected"
6249 }
6250 run_test 56o "check lfs find -mtime for old files"
6251
6252 test_56ob() {
6253         local dir=$DIR/$tdir
6254         local expected=1
6255         local count=0
6256
6257         # just to make sure there is something that won't be found
6258         test_mkdir $dir
6259         touch $dir/$tfile.now
6260
6261         for age in year week day hour min; do
6262                 count=$((count + 1))
6263
6264                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6265                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6266                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6267
6268                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6269                 local nums=$($cmd | wc -l)
6270                 [ $nums -eq $expected ] ||
6271                         error "'$cmd' wrong: found $nums, expected $expected"
6272
6273                 cmd="$LFS find $dir -atime $count${age:0:1}"
6274                 nums=$($cmd | wc -l)
6275                 [ $nums -eq $expected ] ||
6276                         error "'$cmd' wrong: found $nums, expected $expected"
6277         done
6278
6279         sleep 2
6280         cmd="$LFS find $dir -ctime +1s -type f"
6281         nums=$($cmd | wc -l)
6282         (( $nums == $count * 2 + 1)) ||
6283                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6284 }
6285 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6286
6287 test_newerXY_base() {
6288         local x=$1
6289         local y=$2
6290         local dir=$DIR/$tdir
6291         local ref
6292         local negref
6293
6294         if [ $y == "t" ]; then
6295                 if [ $x == "b" ]; then
6296                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6297                 else
6298                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6299                 fi
6300         else
6301                 ref=$DIR/$tfile.newer.$x$y
6302                 touch $ref || error "touch $ref failed"
6303         fi
6304
6305         echo "before = $ref"
6306         sleep 2
6307         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6308         sleep 2
6309         if [ $y == "t" ]; then
6310                 if [ $x == "b" ]; then
6311                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6312                 else
6313                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6314                 fi
6315         else
6316                 negref=$DIR/$tfile.negnewer.$x$y
6317                 touch $negref || error "touch $negref failed"
6318         fi
6319
6320         echo "after = $negref"
6321         local cmd="$LFS find $dir -newer$x$y $ref"
6322         local nums=$(eval $cmd | wc -l)
6323         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6324
6325         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6326                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6327
6328         cmd="$LFS find $dir ! -newer$x$y $negref"
6329         nums=$(eval $cmd | wc -l)
6330         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6331                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6332
6333         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6334         nums=$(eval $cmd | wc -l)
6335         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6336                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6337
6338         rm -rf $DIR/*
6339 }
6340
6341 test_56oc() {
6342         test_newerXY_base "a" "a"
6343         test_newerXY_base "a" "m"
6344         test_newerXY_base "a" "c"
6345         test_newerXY_base "m" "a"
6346         test_newerXY_base "m" "m"
6347         test_newerXY_base "m" "c"
6348         test_newerXY_base "c" "a"
6349         test_newerXY_base "c" "m"
6350         test_newerXY_base "c" "c"
6351
6352         [[ -n "$sles_version" ]] &&
6353                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6354
6355         test_newerXY_base "a" "t"
6356         test_newerXY_base "m" "t"
6357         test_newerXY_base "c" "t"
6358
6359         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6360            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6361                 ! btime_supported && echo "btime unsupported" && return 0
6362
6363         test_newerXY_base "b" "b"
6364         test_newerXY_base "b" "t"
6365 }
6366 run_test 56oc "check lfs find -newerXY work"
6367
6368 btime_supported() {
6369         local dir=$DIR/$tdir
6370         local rc
6371
6372         mkdir -p $dir
6373         touch $dir/$tfile
6374         $LFS find $dir -btime -1d -type f
6375         rc=$?
6376         rm -rf $dir
6377         return $rc
6378 }
6379
6380 test_56od() {
6381         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6382                 ! btime_supported && skip "btime unsupported on MDS"
6383
6384         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6385                 ! btime_supported && skip "btime unsupported on clients"
6386
6387         local dir=$DIR/$tdir
6388         local ref=$DIR/$tfile.ref
6389         local negref=$DIR/$tfile.negref
6390
6391         mkdir $dir || error "mkdir $dir failed"
6392         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6393         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6394         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6395         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6396         touch $ref || error "touch $ref failed"
6397         # sleep 3 seconds at least
6398         sleep 3
6399
6400         local before=$(do_facet mds1 date +%s)
6401         local skew=$(($(date +%s) - before + 1))
6402
6403         if (( skew < 0 && skew > -5 )); then
6404                 sleep $((0 - skew + 1))
6405                 skew=0
6406         fi
6407
6408         # Set the dir stripe params to limit files all on MDT0,
6409         # otherwise we need to calc the max clock skew between
6410         # the client and MDTs.
6411         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6412         sleep 2
6413         touch $negref || error "touch $negref failed"
6414
6415         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6416         local nums=$($cmd | wc -l)
6417         local expected=$(((NUMFILES + 1) * NUMDIRS))
6418
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6423         nums=$($cmd | wc -l)
6424         expected=$((NUMFILES + 1))
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427
6428         [ $skew -lt 0 ] && return
6429
6430         local after=$(do_facet mds1 date +%s)
6431         local age=$((after - before + 1 + skew))
6432
6433         cmd="$LFS find $dir -btime -${age}s -type f"
6434         nums=$($cmd | wc -l)
6435         expected=$(((NUMFILES + 1) * NUMDIRS))
6436
6437         echo "Clock skew between client and server: $skew, age:$age"
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=$(($NUMDIRS + 1))
6442         cmd="$LFS find $dir -btime -${age}s -type d"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446         rm -f $ref $negref || error "Failed to remove $ref $negref"
6447 }
6448 run_test 56od "check lfs find -btime with units"
6449
6450 test_56p() {
6451         [ $RUNAS_ID -eq $UID ] &&
6452                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6453
6454         local dir=$DIR/$tdir
6455
6456         setup_56 $dir $NUMFILES $NUMDIRS
6457         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6458
6459         local expected=$NUMFILES
6460         local cmd="$LFS find -uid $RUNAS_ID $dir"
6461         local nums=$($cmd | wc -l)
6462
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465
6466         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6467         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471 }
6472 run_test 56p "check lfs find -uid and ! -uid"
6473
6474 test_56q() {
6475         [ $RUNAS_ID -eq $UID ] &&
6476                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6477
6478         local dir=$DIR/$tdir
6479
6480         setup_56 $dir $NUMFILES $NUMDIRS
6481         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6482
6483         local expected=$NUMFILES
6484         local cmd="$LFS find -gid $RUNAS_GID $dir"
6485         local nums=$($cmd | wc -l)
6486
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6491         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495 }
6496 run_test 56q "check lfs find -gid and ! -gid"
6497
6498 test_56r() {
6499         local dir=$DIR/$tdir
6500
6501         setup_56 $dir $NUMFILES $NUMDIRS
6502
6503         local expected=12
6504         local cmd="$LFS find -size 0 -type f -lazy $dir"
6505         local nums=$($cmd | wc -l)
6506
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509         cmd="$LFS find -size 0 -type f $dir"
6510         nums=$($cmd | wc -l)
6511         [ $nums -eq $expected ] ||
6512                 error "'$cmd' wrong: found $nums, expected $expected"
6513
6514         expected=0
6515         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6516         nums=$($cmd | wc -l)
6517         [ $nums -eq $expected ] ||
6518                 error "'$cmd' wrong: found $nums, expected $expected"
6519         cmd="$LFS find ! -size 0 -type f $dir"
6520         nums=$($cmd | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523
6524         echo "test" > $dir/$tfile
6525         echo "test2" > $dir/$tfile.2 && sync
6526         expected=1
6527         cmd="$LFS find -size 5 -type f -lazy $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531         cmd="$LFS find -size 5 -type f $dir"
6532         nums=$($cmd | wc -l)
6533         [ $nums -eq $expected ] ||
6534                 error "'$cmd' wrong: found $nums, expected $expected"
6535
6536         expected=1
6537         cmd="$LFS find -size +5 -type f -lazy $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541         cmd="$LFS find -size +5 -type f $dir"
6542         nums=$($cmd | wc -l)
6543         [ $nums -eq $expected ] ||
6544                 error "'$cmd' wrong: found $nums, expected $expected"
6545
6546         expected=2
6547         cmd="$LFS find -size +0 -type f -lazy $dir"
6548         nums=$($cmd | wc -l)
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551         cmd="$LFS find -size +0 -type f $dir"
6552         nums=$($cmd | wc -l)
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         expected=2
6557         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6558         nums=$($cmd | wc -l)
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561         cmd="$LFS find ! -size -5 -type f $dir"
6562         nums=$($cmd | wc -l)
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565
6566         expected=12
6567         cmd="$LFS find -size -5 -type f -lazy $dir"
6568         nums=$($cmd | wc -l)
6569         [ $nums -eq $expected ] ||
6570                 error "'$cmd' wrong: found $nums, expected $expected"
6571         cmd="$LFS find -size -5 -type f $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575 }
6576 run_test 56r "check lfs find -size works"
6577
6578 test_56ra_sub() {
6579         local expected=$1
6580         local glimpses=$2
6581         local cmd="$3"
6582
6583         cancel_lru_locks $OSC
6584
6585         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6586         local nums=$($cmd | wc -l)
6587
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590
6591         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6592
6593         if (( rpcs_before + glimpses != rpcs_after )); then
6594                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6595                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6596
6597                 if [[ $glimpses == 0 ]]; then
6598                         error "'$cmd' should not send glimpse RPCs to OST"
6599                 else
6600                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6601                 fi
6602         fi
6603 }
6604
6605 test_56ra() {
6606         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6607                 skip "MDS < 2.12.58 doesn't return LSOM data"
6608         local dir=$DIR/$tdir
6609         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6610
6611         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6612
6613         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6614         $LCTL set_param -n llite.*.statahead_agl=0
6615         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6616
6617         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6618         # open and close all files to ensure LSOM is updated
6619         cancel_lru_locks $OSC
6620         find $dir -type f | xargs cat > /dev/null
6621
6622         #   expect_found  glimpse_rpcs  command_to_run
6623         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6624         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6625         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6626         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6627
6628         echo "test" > $dir/$tfile
6629         echo "test2" > $dir/$tfile.2 && sync
6630         cancel_lru_locks $OSC
6631         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6632
6633         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6634         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6635         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6636         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6637
6638         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6639         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6640         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6641         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6642         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6643         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6644 }
6645 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6646
6647 test_56rb() {
6648         local dir=$DIR/$tdir
6649         local tmp=$TMP/$tfile.log
6650         local mdt_idx;
6651
6652         test_mkdir -p $dir || error "failed to mkdir $dir"
6653         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6654                 error "failed to setstripe $dir/$tfile"
6655         mdt_idx=$($LFS getdirstripe -i $dir)
6656         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6657
6658         stack_trap "rm -f $tmp" EXIT
6659         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6660         ! grep -q obd_uuid $tmp ||
6661                 error "failed to find --size +100K --ost 0 $dir"
6662         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6663         ! grep -q obd_uuid $tmp ||
6664                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6665 }
6666 run_test 56rb "check lfs find --size --ost/--mdt works"
6667
6668 test_56s() { # LU-611 #LU-9369
6669         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6670
6671         local dir=$DIR/$tdir
6672         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6673
6674         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6675         for i in $(seq $NUMDIRS); do
6676                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6677         done
6678
6679         local expected=$NUMDIRS
6680         local cmd="$LFS find -c $OSTCOUNT $dir"
6681         local nums=$($cmd | wc -l)
6682
6683         [ $nums -eq $expected ] || {
6684                 $LFS getstripe -R $dir
6685                 error "'$cmd' wrong: found $nums, expected $expected"
6686         }
6687
6688         expected=$((NUMDIRS + onestripe))
6689         cmd="$LFS find -stripe-count +0 -type f $dir"
6690         nums=$($cmd | wc -l)
6691         [ $nums -eq $expected ] || {
6692                 $LFS getstripe -R $dir
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         }
6695
6696         expected=$onestripe
6697         cmd="$LFS find -stripe-count 1 -type f $dir"
6698         nums=$($cmd | wc -l)
6699         [ $nums -eq $expected ] || {
6700                 $LFS getstripe -R $dir
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         }
6703
6704         cmd="$LFS find -stripe-count -2 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] || {
6707                 $LFS getstripe -R $dir
6708                 error "'$cmd' wrong: found $nums, expected $expected"
6709         }
6710
6711         expected=0
6712         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718 }
6719 run_test 56s "check lfs find -stripe-count works"
6720
6721 test_56t() { # LU-611 #LU-9369
6722         local dir=$DIR/$tdir
6723
6724         setup_56 $dir 0 $NUMDIRS
6725         for i in $(seq $NUMDIRS); do
6726                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6727         done
6728
6729         local expected=$NUMDIRS
6730         local cmd="$LFS find -S 8M $dir"
6731         local nums=$($cmd | wc -l)
6732
6733         [ $nums -eq $expected ] || {
6734                 $LFS getstripe -R $dir
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736         }
6737         rm -rf $dir
6738
6739         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6740
6741         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6742
6743         expected=$(((NUMDIRS + 1) * NUMFILES))
6744         cmd="$LFS find -stripe-size 512k -type f $dir"
6745         nums=$($cmd | wc -l)
6746         [ $nums -eq $expected ] ||
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748
6749         cmd="$LFS find -stripe-size +320k -type f $dir"
6750         nums=$($cmd | wc -l)
6751         [ $nums -eq $expected ] ||
6752                 error "'$cmd' wrong: found $nums, expected $expected"
6753
6754         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6755         cmd="$LFS find -stripe-size +200k -type f $dir"
6756         nums=$($cmd | wc -l)
6757         [ $nums -eq $expected ] ||
6758                 error "'$cmd' wrong: found $nums, expected $expected"
6759
6760         cmd="$LFS find -stripe-size -640k -type f $dir"
6761         nums=$($cmd | wc -l)
6762         [ $nums -eq $expected ] ||
6763                 error "'$cmd' wrong: found $nums, expected $expected"
6764
6765         expected=4
6766         cmd="$LFS find -stripe-size 256k -type f $dir"
6767         nums=$($cmd | wc -l)
6768         [ $nums -eq $expected ] ||
6769                 error "'$cmd' wrong: found $nums, expected $expected"
6770
6771         cmd="$LFS find -stripe-size -320k -type f $dir"
6772         nums=$($cmd | wc -l)
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         expected=0
6777         cmd="$LFS find -stripe-size 1024k -type f $dir"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781 }
6782 run_test 56t "check lfs find -stripe-size works"
6783
6784 test_56u() { # LU-611
6785         local dir=$DIR/$tdir
6786
6787         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6788
6789         if [[ $OSTCOUNT -gt 1 ]]; then
6790                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6791                 onestripe=4
6792         else
6793                 onestripe=0
6794         fi
6795
6796         local expected=$(((NUMDIRS + 1) * NUMFILES))
6797         local cmd="$LFS find -stripe-index 0 -type f $dir"
6798         local nums=$($cmd | wc -l)
6799
6800         [ $nums -eq $expected ] ||
6801                 error "'$cmd' wrong: found $nums, expected $expected"
6802
6803         expected=$onestripe
6804         cmd="$LFS find -stripe-index 1 -type f $dir"
6805         nums=$($cmd | wc -l)
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808
6809         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6810         nums=$($cmd | wc -l)
6811         [ $nums -eq $expected ] ||
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813
6814         expected=0
6815         # This should produce an error and not return any files
6816         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6817         nums=$($cmd 2>/dev/null | wc -l)
6818         [ $nums -eq $expected ] ||
6819                 error "'$cmd' wrong: found $nums, expected $expected"
6820
6821         if [[ $OSTCOUNT -gt 1 ]]; then
6822                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6823                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6824                 nums=$($cmd | wc -l)
6825                 [ $nums -eq $expected ] ||
6826                         error "'$cmd' wrong: found $nums, expected $expected"
6827         fi
6828 }
6829 run_test 56u "check lfs find -stripe-index works"
6830
6831 test_56v() {
6832         local mdt_idx=0
6833         local dir=$DIR/$tdir
6834
6835         setup_56 $dir $NUMFILES $NUMDIRS
6836
6837         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6838         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6839
6840         for file in $($LFS find -m $UUID $dir); do
6841                 file_midx=$($LFS getstripe -m $file)
6842                 [ $file_midx -eq $mdt_idx ] ||
6843                         error "lfs find -m $UUID != getstripe -m $file_midx"
6844         done
6845 }
6846 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6847
6848 test_56w() {
6849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6851
6852         local dir=$DIR/$tdir
6853
6854         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6855
6856         local stripe_size=$($LFS getstripe -S -d $dir) ||
6857                 error "$LFS getstripe -S -d $dir failed"
6858         stripe_size=${stripe_size%% *}
6859
6860         local file_size=$((stripe_size * OSTCOUNT))
6861         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6862         local required_space=$((file_num * file_size))
6863         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6864                            head -n1)
6865         [[ $free_space -le $((required_space / 1024)) ]] &&
6866                 skip_env "need $required_space, have $free_space kbytes"
6867
6868         local dd_bs=65536
6869         local dd_count=$((file_size / dd_bs))
6870
6871         # write data into the files
6872         local i
6873         local j
6874         local file
6875
6876         for i in $(seq $NUMFILES); do
6877                 file=$dir/file$i
6878                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6879                         error "write data into $file failed"
6880         done
6881         for i in $(seq $NUMDIRS); do
6882                 for j in $(seq $NUMFILES); do
6883                         file=$dir/dir$i/file$j
6884                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6885                                 error "write data into $file failed"
6886                 done
6887         done
6888
6889         # $LFS_MIGRATE will fail if hard link migration is unsupported
6890         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6891                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6892                         error "creating links to $dir/dir1/file1 failed"
6893         fi
6894
6895         local expected=-1
6896
6897         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6898
6899         # lfs_migrate file
6900         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6901
6902         echo "$cmd"
6903         eval $cmd || error "$cmd failed"
6904
6905         check_stripe_count $dir/file1 $expected
6906
6907         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6908         then
6909                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6910                 # OST 1 if it is on OST 0. This file is small enough to
6911                 # be on only one stripe.
6912                 file=$dir/migr_1_ost
6913                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6914                         error "write data into $file failed"
6915                 local obdidx=$($LFS getstripe -i $file)
6916                 local oldmd5=$(md5sum $file)
6917                 local newobdidx=0
6918
6919                 [[ $obdidx -eq 0 ]] && newobdidx=1
6920                 cmd="$LFS migrate -i $newobdidx $file"
6921                 echo $cmd
6922                 eval $cmd || error "$cmd failed"
6923
6924                 local realobdix=$($LFS getstripe -i $file)
6925                 local newmd5=$(md5sum $file)
6926
6927                 [[ $newobdidx -ne $realobdix ]] &&
6928                         error "new OST is different (was=$obdidx, "\
6929                               "wanted=$newobdidx, got=$realobdix)"
6930                 [[ "$oldmd5" != "$newmd5" ]] &&
6931                         error "md5sum differ: $oldmd5, $newmd5"
6932         fi
6933
6934         # lfs_migrate dir
6935         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6936         echo "$cmd"
6937         eval $cmd || error "$cmd failed"
6938
6939         for j in $(seq $NUMFILES); do
6940                 check_stripe_count $dir/dir1/file$j $expected
6941         done
6942
6943         # lfs_migrate works with lfs find
6944         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6945              $LFS_MIGRATE -y -c $expected"
6946         echo "$cmd"
6947         eval $cmd || error "$cmd failed"
6948
6949         for i in $(seq 2 $NUMFILES); do
6950                 check_stripe_count $dir/file$i $expected
6951         done
6952         for i in $(seq 2 $NUMDIRS); do
6953                 for j in $(seq $NUMFILES); do
6954                 check_stripe_count $dir/dir$i/file$j $expected
6955                 done
6956         done
6957 }
6958 run_test 56w "check lfs_migrate -c stripe_count works"
6959
6960 test_56wb() {
6961         local file1=$DIR/$tdir/file1
6962         local create_pool=false
6963         local initial_pool=$($LFS getstripe -p $DIR)
6964         local pool_list=()
6965         local pool=""
6966
6967         echo -n "Creating test dir..."
6968         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6969         echo "done."
6970
6971         echo -n "Creating test file..."
6972         touch $file1 || error "cannot create file"
6973         echo "done."
6974
6975         echo -n "Detecting existing pools..."
6976         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6977
6978         if [ ${#pool_list[@]} -gt 0 ]; then
6979                 echo "${pool_list[@]}"
6980                 for thispool in "${pool_list[@]}"; do
6981                         if [[ -z "$initial_pool" ||
6982                               "$initial_pool" != "$thispool" ]]; then
6983                                 pool="$thispool"
6984                                 echo "Using existing pool '$pool'"
6985                                 break
6986                         fi
6987                 done
6988         else
6989                 echo "none detected."
6990         fi
6991         if [ -z "$pool" ]; then
6992                 pool=${POOL:-testpool}
6993                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6994                 echo -n "Creating pool '$pool'..."
6995                 create_pool=true
6996                 pool_add $pool &> /dev/null ||
6997                         error "pool_add failed"
6998                 echo "done."
6999
7000                 echo -n "Adding target to pool..."
7001                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7002                         error "pool_add_targets failed"
7003                 echo "done."
7004         fi
7005
7006         echo -n "Setting pool using -p option..."
7007         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7008                 error "migrate failed rc = $?"
7009         echo "done."
7010
7011         echo -n "Verifying test file is in pool after migrating..."
7012         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7013                 error "file was not migrated to pool $pool"
7014         echo "done."
7015
7016         echo -n "Removing test file from pool '$pool'..."
7017         # "lfs migrate $file" won't remove the file from the pool
7018         # until some striping information is changed.
7019         $LFS migrate -c 1 $file1 &> /dev/null ||
7020                 error "cannot remove from pool"
7021         [ "$($LFS getstripe -p $file1)" ] &&
7022                 error "pool still set"
7023         echo "done."
7024
7025         echo -n "Setting pool using --pool option..."
7026         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7027                 error "migrate failed rc = $?"
7028         echo "done."
7029
7030         # Clean up
7031         rm -f $file1
7032         if $create_pool; then
7033                 destroy_test_pools 2> /dev/null ||
7034                         error "destroy test pools failed"
7035         fi
7036 }
7037 run_test 56wb "check lfs_migrate pool support"
7038
7039 test_56wc() {
7040         local file1="$DIR/$tdir/file1"
7041         local parent_ssize
7042         local parent_scount
7043         local cur_ssize
7044         local cur_scount
7045         local orig_ssize
7046
7047         echo -n "Creating test dir..."
7048         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7049         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7050                 error "cannot set stripe by '-S 1M -c 1'"
7051         echo "done"
7052
7053         echo -n "Setting initial stripe for test file..."
7054         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7055                 error "cannot set stripe"
7056         cur_ssize=$($LFS getstripe -S "$file1")
7057         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7058         echo "done."
7059
7060         # File currently set to -S 512K -c 1
7061
7062         # Ensure -c and -S options are rejected when -R is set
7063         echo -n "Verifying incompatible options are detected..."
7064         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7065                 error "incompatible -c and -R options not detected"
7066         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7067                 error "incompatible -S and -R options not detected"
7068         echo "done."
7069
7070         # Ensure unrecognized options are passed through to 'lfs migrate'
7071         echo -n "Verifying -S option is passed through to lfs migrate..."
7072         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7073                 error "migration failed"
7074         cur_ssize=$($LFS getstripe -S "$file1")
7075         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7076         echo "done."
7077
7078         # File currently set to -S 1M -c 1
7079
7080         # Ensure long options are supported
7081         echo -n "Verifying long options supported..."
7082         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7083                 error "long option without argument not supported"
7084         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7085                 error "long option with argument not supported"
7086         cur_ssize=$($LFS getstripe -S "$file1")
7087         [ $cur_ssize -eq 524288 ] ||
7088                 error "migrate --stripe-size $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         if [ "$OSTCOUNT" -gt 1 ]; then
7094                 echo -n "Verifying explicit stripe count can be set..."
7095                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7096                         error "migrate failed"
7097                 cur_scount=$($LFS getstripe -c "$file1")
7098                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7099                 echo "done."
7100         fi
7101
7102         # File currently set to -S 512K -c 1 or -S 512K -c 2
7103
7104         # Ensure parent striping is used if -R is set, and no stripe
7105         # count or size is specified
7106         echo -n "Setting stripe for parent directory..."
7107         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7108                 error "cannot set stripe '-S 2M -c 1'"
7109         echo "done."
7110
7111         echo -n "Verifying restripe option uses parent stripe settings..."
7112         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7113         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7114         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7115                 error "migrate failed"
7116         cur_ssize=$($LFS getstripe -S "$file1")
7117         [ $cur_ssize -eq $parent_ssize ] ||
7118                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7119         cur_scount=$($LFS getstripe -c "$file1")
7120         [ $cur_scount -eq $parent_scount ] ||
7121                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7122         echo "done."
7123
7124         # File currently set to -S 1M -c 1
7125
7126         # Ensure striping is preserved if -R is not set, and no stripe
7127         # count or size is specified
7128         echo -n "Verifying striping size preserved when not specified..."
7129         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7130         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7131                 error "cannot set stripe on parent directory"
7132         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7133                 error "migrate failed"
7134         cur_ssize=$($LFS getstripe -S "$file1")
7135         [ $cur_ssize -eq $orig_ssize ] ||
7136                 error "migrate by default $cur_ssize != $orig_ssize"
7137         echo "done."
7138
7139         # Ensure file name properly detected when final option has no argument
7140         echo -n "Verifying file name properly detected..."
7141         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7142                 error "file name interpreted as option argument"
7143         echo "done."
7144
7145         # Clean up
7146         rm -f "$file1"
7147 }
7148 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7149
7150 test_56wd() {
7151         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7152
7153         local file1=$DIR/$tdir/file1
7154
7155         echo -n "Creating test dir..."
7156         test_mkdir $DIR/$tdir || error "cannot create dir"
7157         echo "done."
7158
7159         echo -n "Creating test file..."
7160         touch $file1
7161         echo "done."
7162
7163         # Ensure 'lfs migrate' will fail by using a non-existent option,
7164         # and make sure rsync is not called to recover
7165         echo -n "Make sure --no-rsync option works..."
7166         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7167                 grep -q 'refusing to fall back to rsync' ||
7168                 error "rsync was called with --no-rsync set"
7169         echo "done."
7170
7171         # Ensure rsync is called without trying 'lfs migrate' first
7172         echo -n "Make sure --rsync option works..."
7173         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7174                 grep -q 'falling back to rsync' &&
7175                 error "lfs migrate was called with --rsync set"
7176         echo "done."
7177
7178         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7179         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7180                 grep -q 'at the same time' ||
7181                 error "--rsync and --no-rsync accepted concurrently"
7182         echo "done."
7183
7184         # Clean up
7185         rm -f $file1
7186 }
7187 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7188
7189 test_56we() {
7190         local td=$DIR/$tdir
7191         local tf=$td/$tfile
7192
7193         test_mkdir $td || error "cannot create $td"
7194         touch $tf || error "cannot touch $tf"
7195
7196         echo -n "Make sure --non-direct|-D works..."
7197         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7198                 grep -q "lfs migrate --non-direct" ||
7199                 error "--non-direct option cannot work correctly"
7200         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7201                 grep -q "lfs migrate -D" ||
7202                 error "-D option cannot work correctly"
7203         echo "done."
7204 }
7205 run_test 56we "check lfs_migrate --non-direct|-D support"
7206
7207 test_56x() {
7208         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7209         check_swap_layouts_support
7210
7211         local dir=$DIR/$tdir
7212         local ref1=/etc/passwd
7213         local file1=$dir/file1
7214
7215         test_mkdir $dir || error "creating dir $dir"
7216         $LFS setstripe -c 2 $file1
7217         cp $ref1 $file1
7218         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7219         stripe=$($LFS getstripe -c $file1)
7220         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7221         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7222
7223         # clean up
7224         rm -f $file1
7225 }
7226 run_test 56x "lfs migration support"
7227
7228 test_56xa() {
7229         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7230         check_swap_layouts_support
7231
7232         local dir=$DIR/$tdir/$testnum
7233
7234         test_mkdir -p $dir
7235
7236         local ref1=/etc/passwd
7237         local file1=$dir/file1
7238
7239         $LFS setstripe -c 2 $file1
7240         cp $ref1 $file1
7241         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7242
7243         local stripe=$($LFS getstripe -c $file1)
7244
7245         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7246         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7247
7248         # clean up
7249         rm -f $file1
7250 }
7251 run_test 56xa "lfs migration --block support"
7252
7253 check_migrate_links() {
7254         local dir="$1"
7255         local file1="$dir/file1"
7256         local begin="$2"
7257         local count="$3"
7258         local runas="$4"
7259         local total_count=$(($begin + $count - 1))
7260         local symlink_count=10
7261         local uniq_count=10
7262
7263         if [ ! -f "$file1" ]; then
7264                 echo -n "creating initial file..."
7265                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7266                         error "cannot setstripe initial file"
7267                 echo "done"
7268
7269                 echo -n "creating symlinks..."
7270                 for s in $(seq 1 $symlink_count); do
7271                         ln -s "$file1" "$dir/slink$s" ||
7272                                 error "cannot create symlinks"
7273                 done
7274                 echo "done"
7275
7276                 echo -n "creating nonlinked files..."
7277                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7278                         error "cannot create nonlinked files"
7279                 echo "done"
7280         fi
7281
7282         # create hard links
7283         if [ ! -f "$dir/file$total_count" ]; then
7284                 echo -n "creating hard links $begin:$total_count..."
7285                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7286                         /dev/null || error "cannot create hard links"
7287                 echo "done"
7288         fi
7289
7290         echo -n "checking number of hard links listed in xattrs..."
7291         local fid=$($LFS getstripe -F "$file1")
7292         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7293
7294         echo "${#paths[*]}"
7295         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7296                         skip "hard link list has unexpected size, skipping test"
7297         fi
7298         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7299                         error "link names should exceed xattrs size"
7300         fi
7301
7302         echo -n "migrating files..."
7303         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7304         local rc=$?
7305         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7306         echo "done"
7307
7308         # make sure all links have been properly migrated
7309         echo -n "verifying files..."
7310         fid=$($LFS getstripe -F "$file1") ||
7311                 error "cannot get fid for file $file1"
7312         for i in $(seq 2 $total_count); do
7313                 local fid2=$($LFS getstripe -F $dir/file$i)
7314
7315                 [ "$fid2" == "$fid" ] ||
7316                         error "migrated hard link has mismatched FID"
7317         done
7318
7319         # make sure hard links were properly detected, and migration was
7320         # performed only once for the entire link set; nonlinked files should
7321         # also be migrated
7322         local actual=$(grep -c 'done' <<< "$migrate_out")
7323         local expected=$(($uniq_count + 1))
7324
7325         [ "$actual" -eq  "$expected" ] ||
7326                 error "hard links individually migrated ($actual != $expected)"
7327
7328         # make sure the correct number of hard links are present
7329         local hardlinks=$(stat -c '%h' "$file1")
7330
7331         [ $hardlinks -eq $total_count ] ||
7332                 error "num hard links $hardlinks != $total_count"
7333         echo "done"
7334
7335         return 0
7336 }
7337
7338 test_56xb() {
7339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7340                 skip "Need MDS version at least 2.10.55"
7341
7342         local dir="$DIR/$tdir"
7343
7344         test_mkdir "$dir" || error "cannot create dir $dir"
7345
7346         echo "testing lfs migrate mode when all links fit within xattrs"
7347         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7348
7349         echo "testing rsync mode when all links fit within xattrs"
7350         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7351
7352         echo "testing lfs migrate mode when all links do not fit within xattrs"
7353         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7354
7355         echo "testing rsync mode when all links do not fit within xattrs"
7356         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7357
7358         chown -R $RUNAS_ID $dir
7359         echo "testing non-root lfs migrate mode when not all links are in xattr"
7360         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7361
7362         # clean up
7363         rm -rf $dir
7364 }
7365 run_test 56xb "lfs migration hard link support"
7366
7367 test_56xc() {
7368         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7369
7370         local dir="$DIR/$tdir"
7371
7372         test_mkdir "$dir" || error "cannot create dir $dir"
7373
7374         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7375         echo -n "Setting initial stripe for 20MB test file..."
7376         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7377                 error "cannot setstripe 20MB file"
7378         echo "done"
7379         echo -n "Sizing 20MB test file..."
7380         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7381         echo "done"
7382         echo -n "Verifying small file autostripe count is 1..."
7383         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7384                 error "cannot migrate 20MB file"
7385         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7386                 error "cannot get stripe for $dir/20mb"
7387         [ $stripe_count -eq 1 ] ||
7388                 error "unexpected stripe count $stripe_count for 20MB file"
7389         rm -f "$dir/20mb"
7390         echo "done"
7391
7392         # Test 2: File is small enough to fit within the available space on
7393         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7394         # have at least an additional 1KB for each desired stripe for test 3
7395         echo -n "Setting stripe for 1GB test file..."
7396         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7397         echo "done"
7398         echo -n "Sizing 1GB test file..."
7399         # File size is 1GB + 3KB
7400         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7401         echo "done"
7402
7403         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7404         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7405         if (( avail > 524288 * OSTCOUNT )); then
7406                 echo -n "Migrating 1GB file..."
7407                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7408                         error "cannot migrate 1GB file"
7409                 echo "done"
7410                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7411                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7412                         error "cannot getstripe for 1GB file"
7413                 [ $stripe_count -eq 2 ] ||
7414                         error "unexpected stripe count $stripe_count != 2"
7415                 echo "done"
7416         fi
7417
7418         # Test 3: File is too large to fit within the available space on
7419         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7420         if [ $OSTCOUNT -ge 3 ]; then
7421                 # The required available space is calculated as
7422                 # file size (1GB + 3KB) / OST count (3).
7423                 local kb_per_ost=349526
7424
7425                 echo -n "Migrating 1GB file with limit..."
7426                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7427                         error "cannot migrate 1GB file with limit"
7428                 echo "done"
7429
7430                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7431                 echo -n "Verifying 1GB autostripe count with limited space..."
7432                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7433                         error "unexpected stripe count $stripe_count (min 3)"
7434                 echo "done"
7435         fi
7436
7437         # clean up
7438         rm -rf $dir
7439 }
7440 run_test 56xc "lfs migration autostripe"
7441
7442 test_56xd() {
7443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7444
7445         local dir=$DIR/$tdir
7446         local f_mgrt=$dir/$tfile.mgrt
7447         local f_yaml=$dir/$tfile.yaml
7448         local f_copy=$dir/$tfile.copy
7449         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7450         local layout_copy="-c 2 -S 2M -i 1"
7451         local yamlfile=$dir/yamlfile
7452         local layout_before;
7453         local layout_after;
7454
7455         test_mkdir "$dir" || error "cannot create dir $dir"
7456         $LFS setstripe $layout_yaml $f_yaml ||
7457                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7458         $LFS getstripe --yaml $f_yaml > $yamlfile
7459         $LFS setstripe $layout_copy $f_copy ||
7460                 error "cannot setstripe $f_copy with layout $layout_copy"
7461         touch $f_mgrt
7462         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7463
7464         # 1. test option --yaml
7465         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7466                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7467         layout_before=$(get_layout_param $f_yaml)
7468         layout_after=$(get_layout_param $f_mgrt)
7469         [ "$layout_after" == "$layout_before" ] ||
7470                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7471
7472         # 2. test option --copy
7473         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7474                 error "cannot migrate $f_mgrt with --copy $f_copy"
7475         layout_before=$(get_layout_param $f_copy)
7476         layout_after=$(get_layout_param $f_mgrt)
7477         [ "$layout_after" == "$layout_before" ] ||
7478                 error "lfs_migrate --copy: $layout_after != $layout_before"
7479 }
7480 run_test 56xd "check lfs_migrate --yaml and --copy support"
7481
7482 test_56xe() {
7483         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7484
7485         local dir=$DIR/$tdir
7486         local f_comp=$dir/$tfile
7487         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7488         local layout_before=""
7489         local layout_after=""
7490
7491         test_mkdir "$dir" || error "cannot create dir $dir"
7492         $LFS setstripe $layout $f_comp ||
7493                 error "cannot setstripe $f_comp with layout $layout"
7494         layout_before=$(get_layout_param $f_comp)
7495         dd if=/dev/zero of=$f_comp bs=1M count=4
7496
7497         # 1. migrate a comp layout file by lfs_migrate
7498         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7499         layout_after=$(get_layout_param $f_comp)
7500         [ "$layout_before" == "$layout_after" ] ||
7501                 error "lfs_migrate: $layout_before != $layout_after"
7502
7503         # 2. migrate a comp layout file by lfs migrate
7504         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7505         layout_after=$(get_layout_param $f_comp)
7506         [ "$layout_before" == "$layout_after" ] ||
7507                 error "lfs migrate: $layout_before != $layout_after"
7508 }
7509 run_test 56xe "migrate a composite layout file"
7510
7511 test_56xf() {
7512         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7513
7514         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7515                 skip "Need server version at least 2.13.53"
7516
7517         local dir=$DIR/$tdir
7518         local f_comp=$dir/$tfile
7519         local layout="-E 1M -c1 -E -1 -c2"
7520         local fid_before=""
7521         local fid_after=""
7522
7523         test_mkdir "$dir" || error "cannot create dir $dir"
7524         $LFS setstripe $layout $f_comp ||
7525                 error "cannot setstripe $f_comp with layout $layout"
7526         fid_before=$($LFS getstripe --fid $f_comp)
7527         dd if=/dev/zero of=$f_comp bs=1M count=4
7528
7529         # 1. migrate a comp layout file to a comp layout
7530         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7531         fid_after=$($LFS getstripe --fid $f_comp)
7532         [ "$fid_before" == "$fid_after" ] ||
7533                 error "comp-to-comp migrate: $fid_before != $fid_after"
7534
7535         # 2. migrate a comp layout file to a plain layout
7536         $LFS migrate -c2 $f_comp ||
7537                 error "cannot migrate $f_comp by lfs migrate"
7538         fid_after=$($LFS getstripe --fid $f_comp)
7539         [ "$fid_before" == "$fid_after" ] ||
7540                 error "comp-to-plain migrate: $fid_before != $fid_after"
7541
7542         # 3. migrate a plain layout file to a comp layout
7543         $LFS migrate $layout $f_comp ||
7544                 error "cannot migrate $f_comp by lfs migrate"
7545         fid_after=$($LFS getstripe --fid $f_comp)
7546         [ "$fid_before" == "$fid_after" ] ||
7547                 error "plain-to-comp migrate: $fid_before != $fid_after"
7548 }
7549 run_test 56xf "FID is not lost during migration of a composite layout file"
7550
7551 test_56y() {
7552         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7553                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7554
7555         local res=""
7556         local dir=$DIR/$tdir
7557         local f1=$dir/file1
7558         local f2=$dir/file2
7559
7560         test_mkdir -p $dir || error "creating dir $dir"
7561         touch $f1 || error "creating std file $f1"
7562         $MULTIOP $f2 H2c || error "creating released file $f2"
7563
7564         # a directory can be raid0, so ask only for files
7565         res=$($LFS find $dir -L raid0 -type f | wc -l)
7566         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7567
7568         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7569         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7570
7571         # only files can be released, so no need to force file search
7572         res=$($LFS find $dir -L released)
7573         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7574
7575         res=$($LFS find $dir -type f \! -L released)
7576         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7577 }
7578 run_test 56y "lfs find -L raid0|released"
7579
7580 test_56z() { # LU-4824
7581         # This checks to make sure 'lfs find' continues after errors
7582         # There are two classes of errors that should be caught:
7583         # - If multiple paths are provided, all should be searched even if one
7584         #   errors out
7585         # - If errors are encountered during the search, it should not terminate
7586         #   early
7587         local dir=$DIR/$tdir
7588         local i
7589
7590         test_mkdir $dir
7591         for i in d{0..9}; do
7592                 test_mkdir $dir/$i
7593                 touch $dir/$i/$tfile
7594         done
7595         $LFS find $DIR/non_existent_dir $dir &&
7596                 error "$LFS find did not return an error"
7597         # Make a directory unsearchable. This should NOT be the last entry in
7598         # directory order.  Arbitrarily pick the 6th entry
7599         chmod 700 $($LFS find $dir -type d | sed '6!d')
7600
7601         $RUNAS $LFS find $DIR/non_existent $dir
7602         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7603
7604         # The user should be able to see 10 directories and 9 files
7605         (( count == 19 )) ||
7606                 error "$LFS find found $count != 19 entries after error"
7607 }
7608 run_test 56z "lfs find should continue after an error"
7609
7610 test_56aa() { # LU-5937
7611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7612
7613         local dir=$DIR/$tdir
7614
7615         mkdir $dir
7616         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7617
7618         createmany -o $dir/striped_dir/${tfile}- 1024
7619         local dirs=$($LFS find --size +8k $dir/)
7620
7621         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7622 }
7623 run_test 56aa "lfs find --size under striped dir"
7624
7625 test_56ab() { # LU-10705
7626         test_mkdir $DIR/$tdir
7627         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7628         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7629         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7630         # Flush writes to ensure valid blocks.  Need to be more thorough for
7631         # ZFS, since blocks are not allocated/returned to client immediately.
7632         sync_all_data
7633         wait_zfs_commit ost1 2
7634         cancel_lru_locks osc
7635         ls -ls $DIR/$tdir
7636
7637         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7638
7639         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7640
7641         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7642         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7643
7644         rm -f $DIR/$tdir/$tfile.[123]
7645 }
7646 run_test 56ab "lfs find --blocks"
7647
7648 # LU-11188
7649 test_56aca() {
7650         local dir="$DIR/$tdir"
7651         local perms=(001 002 003 004 005 006 007
7652                      010 020 030 040 050 060 070
7653                      100 200 300 400 500 600 700
7654                      111 222 333 444 555 666 777)
7655         local perm_minus=(8 8 4 8 4 4 2
7656                           8 8 4 8 4 4 2
7657                           8 8 4 8 4 4 2
7658                           4 4 2 4 2 2 1)
7659         local perm_slash=(8  8 12  8 12 12 14
7660                           8  8 12  8 12 12 14
7661                           8  8 12  8 12 12 14
7662                          16 16 24 16 24 24 28)
7663
7664         test_mkdir "$dir"
7665         for perm in ${perms[*]}; do
7666                 touch "$dir/$tfile.$perm"
7667                 chmod $perm "$dir/$tfile.$perm"
7668         done
7669
7670         for ((i = 0; i < ${#perms[*]}; i++)); do
7671                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7672                 (( $num == 1 )) ||
7673                         error "lfs find -perm ${perms[i]}:"\
7674                               "$num != 1"
7675
7676                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7677                 (( $num == ${perm_minus[i]} )) ||
7678                         error "lfs find -perm -${perms[i]}:"\
7679                               "$num != ${perm_minus[i]}"
7680
7681                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7682                 (( $num == ${perm_slash[i]} )) ||
7683                         error "lfs find -perm /${perms[i]}:"\
7684                               "$num != ${perm_slash[i]}"
7685         done
7686 }
7687 run_test 56aca "check lfs find -perm with octal representation"
7688
7689 test_56acb() {
7690         local dir=$DIR/$tdir
7691         # p is the permission of write and execute for user, group and other
7692         # without the umask. It is used to test +wx.
7693         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7694         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7695         local symbolic=(+t  a+t u+t g+t o+t
7696                         g+s u+s o+s +s o+sr
7697                         o=r,ug+o,u+w
7698                         u+ g+ o+ a+ ugo+
7699                         u- g- o- a- ugo-
7700                         u= g= o= a= ugo=
7701                         o=r,ug+o,u+w u=r,a+u,u+w
7702                         g=r,ugo=g,u+w u+x,+X +X
7703                         u+x,u+X u+X u+x,g+X o+r,+X
7704                         u+x,go+X +wx +rwx)
7705
7706         test_mkdir $dir
7707         for perm in ${perms[*]}; do
7708                 touch "$dir/$tfile.$perm"
7709                 chmod $perm "$dir/$tfile.$perm"
7710         done
7711
7712         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7713                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7714
7715                 (( $num == 1 )) ||
7716                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7717         done
7718 }
7719 run_test 56acb "check lfs find -perm with symbolic representation"
7720
7721 test_56acc() {
7722         local dir=$DIR/$tdir
7723         local tests="17777 787 789 abcd
7724                 ug=uu ug=a ug=gu uo=ou urw
7725                 u+xg+x a=r,u+x,"
7726
7727         test_mkdir $dir
7728         for err in $tests; do
7729                 if $LFS find $dir -perm $err 2>/dev/null; then
7730                         error "lfs find -perm $err: parsing should have failed"
7731                 fi
7732         done
7733 }
7734 run_test 56acc "check parsing error for lfs find -perm"
7735
7736 test_56ba() {
7737         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7738                 skip "Need MDS version at least 2.10.50"
7739
7740         # Create composite files with one component
7741         local dir=$DIR/$tdir
7742
7743         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7744         # Create composite files with three components
7745         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7746         # Create non-composite files
7747         createmany -o $dir/${tfile}- 10
7748
7749         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7750
7751         [[ $nfiles == 10 ]] ||
7752                 error "lfs find -E 1M found $nfiles != 10 files"
7753
7754         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7755         [[ $nfiles == 25 ]] ||
7756                 error "lfs find ! -E 1M found $nfiles != 25 files"
7757
7758         # All files have a component that starts at 0
7759         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7760         [[ $nfiles == 35 ]] ||
7761                 error "lfs find --component-start 0 - $nfiles != 35 files"
7762
7763         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7764         [[ $nfiles == 15 ]] ||
7765                 error "lfs find --component-start 2M - $nfiles != 15 files"
7766
7767         # All files created here have a componenet that does not starts at 2M
7768         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7769         [[ $nfiles == 35 ]] ||
7770                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7771
7772         # Find files with a specified number of components
7773         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7774         [[ $nfiles == 15 ]] ||
7775                 error "lfs find --component-count 3 - $nfiles != 15 files"
7776
7777         # Remember non-composite files have a component count of zero
7778         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7779         [[ $nfiles == 10 ]] ||
7780                 error "lfs find --component-count 0 - $nfiles != 10 files"
7781
7782         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7783         [[ $nfiles == 20 ]] ||
7784                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7785
7786         # All files have a flag called "init"
7787         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7788         [[ $nfiles == 35 ]] ||
7789                 error "lfs find --component-flags init - $nfiles != 35 files"
7790
7791         # Multi-component files will have a component not initialized
7792         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7793         [[ $nfiles == 15 ]] ||
7794                 error "lfs find !--component-flags init - $nfiles != 15 files"
7795
7796         rm -rf $dir
7797
7798 }
7799 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7800
7801 test_56ca() {
7802         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7803                 skip "Need MDS version at least 2.10.57"
7804
7805         local td=$DIR/$tdir
7806         local tf=$td/$tfile
7807         local dir
7808         local nfiles
7809         local cmd
7810         local i
7811         local j
7812
7813         # create mirrored directories and mirrored files
7814         mkdir $td || error "mkdir $td failed"
7815         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7816         createmany -o $tf- 10 || error "create $tf- failed"
7817
7818         for i in $(seq 2); do
7819                 dir=$td/dir$i
7820                 mkdir $dir || error "mkdir $dir failed"
7821                 $LFS mirror create -N$((3 + i)) $dir ||
7822                         error "create mirrored dir $dir failed"
7823                 createmany -o $dir/$tfile- 10 ||
7824                         error "create $dir/$tfile- failed"
7825         done
7826
7827         # change the states of some mirrored files
7828         echo foo > $tf-6
7829         for i in $(seq 2); do
7830                 dir=$td/dir$i
7831                 for j in $(seq 4 9); do
7832                         echo foo > $dir/$tfile-$j
7833                 done
7834         done
7835
7836         # find mirrored files with specific mirror count
7837         cmd="$LFS find --mirror-count 3 --type f $td"
7838         nfiles=$($cmd | wc -l)
7839         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7840
7841         cmd="$LFS find ! --mirror-count 3 --type f $td"
7842         nfiles=$($cmd | wc -l)
7843         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7844
7845         cmd="$LFS find --mirror-count +2 --type f $td"
7846         nfiles=$($cmd | wc -l)
7847         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7848
7849         cmd="$LFS find --mirror-count -6 --type f $td"
7850         nfiles=$($cmd | wc -l)
7851         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7852
7853         # find mirrored files with specific file state
7854         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7855         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7856
7857         cmd="$LFS find --mirror-state=ro --type f $td"
7858         nfiles=$($cmd | wc -l)
7859         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7860
7861         cmd="$LFS find ! --mirror-state=ro --type f $td"
7862         nfiles=$($cmd | wc -l)
7863         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7864
7865         cmd="$LFS find --mirror-state=wp --type f $td"
7866         nfiles=$($cmd | wc -l)
7867         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7868
7869         cmd="$LFS find ! --mirror-state=sp --type f $td"
7870         nfiles=$($cmd | wc -l)
7871         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7872 }
7873 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7874
7875 test_56da() { # LU-14179
7876         local path=$DIR/$tdir
7877
7878         test_mkdir $path
7879         cd $path
7880
7881         local longdir=$(str_repeat 'a' 255)
7882
7883         for i in {1..15}; do
7884                 path=$path/$longdir
7885                 test_mkdir $longdir
7886                 cd $longdir
7887         done
7888
7889         local len=${#path}
7890         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7891
7892         test_mkdir $lastdir
7893         cd $lastdir
7894         # PATH_MAX-1
7895         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7896
7897         # NAME_MAX
7898         touch $(str_repeat 'f' 255)
7899
7900         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7901                 error "lfs find reported an error"
7902
7903         rm -rf $DIR/$tdir
7904 }
7905 run_test 56da "test lfs find with long paths"
7906
7907 test_57a() {
7908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7909         # note test will not do anything if MDS is not local
7910         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7911                 skip_env "ldiskfs only test"
7912         fi
7913         remote_mds_nodsh && skip "remote MDS with nodsh"
7914
7915         local MNTDEV="osd*.*MDT*.mntdev"
7916         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7917         [ -z "$DEV" ] && error "can't access $MNTDEV"
7918         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7919                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7920                         error "can't access $DEV"
7921                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7922                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7923                 rm $TMP/t57a.dump
7924         done
7925 }
7926 run_test 57a "verify MDS filesystem created with large inodes =="
7927
7928 test_57b() {
7929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7930         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7931                 skip_env "ldiskfs only test"
7932         fi
7933         remote_mds_nodsh && skip "remote MDS with nodsh"
7934
7935         local dir=$DIR/$tdir
7936         local filecount=100
7937         local file1=$dir/f1
7938         local fileN=$dir/f$filecount
7939
7940         rm -rf $dir || error "removing $dir"
7941         test_mkdir -c1 $dir
7942         local mdtidx=$($LFS getstripe -m $dir)
7943         local mdtname=MDT$(printf %04x $mdtidx)
7944         local facet=mds$((mdtidx + 1))
7945
7946         echo "mcreating $filecount files"
7947         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7948
7949         # verify that files do not have EAs yet
7950         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7951                 error "$file1 has an EA"
7952         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7953                 error "$fileN has an EA"
7954
7955         sync
7956         sleep 1
7957         df $dir  #make sure we get new statfs data
7958         local mdsfree=$(do_facet $facet \
7959                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7960         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7961         local file
7962
7963         echo "opening files to create objects/EAs"
7964         for file in $(seq -f $dir/f%g 1 $filecount); do
7965                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7966                         error "opening $file"
7967         done
7968
7969         # verify that files have EAs now
7970         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7971         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7972
7973         sleep 1  #make sure we get new statfs data
7974         df $dir
7975         local mdsfree2=$(do_facet $facet \
7976                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7977         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7978
7979         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7980                 if [ "$mdsfree" != "$mdsfree2" ]; then
7981                         error "MDC before $mdcfree != after $mdcfree2"
7982                 else
7983                         echo "MDC before $mdcfree != after $mdcfree2"
7984                         echo "unable to confirm if MDS has large inodes"
7985                 fi
7986         fi
7987         rm -rf $dir
7988 }
7989 run_test 57b "default LOV EAs are stored inside large inodes ==="
7990
7991 test_58() {
7992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7993         [ -z "$(which wiretest 2>/dev/null)" ] &&
7994                         skip_env "could not find wiretest"
7995
7996         wiretest
7997 }
7998 run_test 58 "verify cross-platform wire constants =============="
7999
8000 test_59() {
8001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8002
8003         echo "touch 130 files"
8004         createmany -o $DIR/f59- 130
8005         echo "rm 130 files"
8006         unlinkmany $DIR/f59- 130
8007         sync
8008         # wait for commitment of removal
8009         wait_delete_completed
8010 }
8011 run_test 59 "verify cancellation of llog records async ========="
8012
8013 TEST60_HEAD="test_60 run $RANDOM"
8014 test_60a() {
8015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8016         remote_mgs_nodsh && skip "remote MGS with nodsh"
8017         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8018                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8019                         skip_env "missing subtest run-llog.sh"
8020
8021         log "$TEST60_HEAD - from kernel mode"
8022         do_facet mgs "$LCTL dk > /dev/null"
8023         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8024         do_facet mgs $LCTL dk > $TMP/$tfile
8025
8026         # LU-6388: test llog_reader
8027         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8028         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8029         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8030                         skip_env "missing llog_reader"
8031         local fstype=$(facet_fstype mgs)
8032         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8033                 skip_env "Only for ldiskfs or zfs type mgs"
8034
8035         local mntpt=$(facet_mntpt mgs)
8036         local mgsdev=$(mgsdevname 1)
8037         local fid_list
8038         local fid
8039         local rec_list
8040         local rec
8041         local rec_type
8042         local obj_file
8043         local path
8044         local seq
8045         local oid
8046         local pass=true
8047
8048         #get fid and record list
8049         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8050                 tail -n 4))
8051         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8052                 tail -n 4))
8053         #remount mgs as ldiskfs or zfs type
8054         stop mgs || error "stop mgs failed"
8055         mount_fstype mgs || error "remount mgs failed"
8056         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8057                 fid=${fid_list[i]}
8058                 rec=${rec_list[i]}
8059                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8060                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8061                 oid=$((16#$oid))
8062
8063                 case $fstype in
8064                         ldiskfs )
8065                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8066                         zfs )
8067                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8068                 esac
8069                 echo "obj_file is $obj_file"
8070                 do_facet mgs $llog_reader $obj_file
8071
8072                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8073                         awk '{ print $3 }' | sed -e "s/^type=//g")
8074                 if [ $rec_type != $rec ]; then
8075                         echo "FAILED test_60a wrong record type $rec_type," \
8076                               "should be $rec"
8077                         pass=false
8078                         break
8079                 fi
8080
8081                 #check obj path if record type is LLOG_LOGID_MAGIC
8082                 if [ "$rec" == "1064553b" ]; then
8083                         path=$(do_facet mgs $llog_reader $obj_file |
8084                                 grep "path=" | awk '{ print $NF }' |
8085                                 sed -e "s/^path=//g")
8086                         if [ $obj_file != $mntpt/$path ]; then
8087                                 echo "FAILED test_60a wrong obj path" \
8088                                       "$montpt/$path, should be $obj_file"
8089                                 pass=false
8090                                 break
8091                         fi
8092                 fi
8093         done
8094         rm -f $TMP/$tfile
8095         #restart mgs before "error", otherwise it will block the next test
8096         stop mgs || error "stop mgs failed"
8097         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8098         $pass || error "test failed, see FAILED test_60a messages for specifics"
8099 }
8100 run_test 60a "llog_test run from kernel module and test llog_reader"
8101
8102 test_60b() { # bug 6411
8103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8104
8105         dmesg > $DIR/$tfile
8106         LLOG_COUNT=$(do_facet mgs dmesg |
8107                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8108                           /llog_[a-z]*.c:[0-9]/ {
8109                                 if (marker)
8110                                         from_marker++
8111                                 from_begin++
8112                           }
8113                           END {
8114                                 if (marker)
8115                                         print from_marker
8116                                 else
8117                                         print from_begin
8118                           }")
8119
8120         [[ $LLOG_COUNT -gt 120 ]] &&
8121                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8122 }
8123 run_test 60b "limit repeated messages from CERROR/CWARN"
8124
8125 test_60c() {
8126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8127
8128         echo "create 5000 files"
8129         createmany -o $DIR/f60c- 5000
8130 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8131         lctl set_param fail_loc=0x80000137
8132         unlinkmany $DIR/f60c- 5000
8133         lctl set_param fail_loc=0
8134 }
8135 run_test 60c "unlink file when mds full"
8136
8137 test_60d() {
8138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8139
8140         SAVEPRINTK=$(lctl get_param -n printk)
8141         # verify "lctl mark" is even working"
8142         MESSAGE="test message ID $RANDOM $$"
8143         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8144         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8145
8146         lctl set_param printk=0 || error "set lnet.printk failed"
8147         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8148         MESSAGE="new test message ID $RANDOM $$"
8149         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8150         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8151         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8152
8153         lctl set_param -n printk="$SAVEPRINTK"
8154 }
8155 run_test 60d "test printk console message masking"
8156
8157 test_60e() {
8158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8159         remote_mds_nodsh && skip "remote MDS with nodsh"
8160
8161         touch $DIR/$tfile
8162 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8163         do_facet mds1 lctl set_param fail_loc=0x15b
8164         rm $DIR/$tfile
8165 }
8166 run_test 60e "no space while new llog is being created"
8167
8168 test_60f() {
8169         local old_path=$($LCTL get_param -n debug_path)
8170
8171         stack_trap "$LCTL set_param debug_path=$old_path"
8172         stack_trap "rm -f $TMP/$tfile*"
8173         rm -f $TMP/$tfile* 2> /dev/null
8174         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8175         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8176         test_mkdir $DIR/$tdir
8177         # retry in case the open is cached and not released
8178         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8179                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8180                 sleep 0.1
8181         done
8182         ls $TMP/$tfile*
8183         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8184 }
8185 run_test 60f "change debug_path works"
8186
8187 test_60g() {
8188         local pid
8189         local i
8190
8191         test_mkdir -c $MDSCOUNT $DIR/$tdir
8192
8193         (
8194                 local index=0
8195                 while true; do
8196                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8197                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8198                                 2>/dev/null
8199                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8200                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8201                         index=$((index + 1))
8202                 done
8203         ) &
8204
8205         pid=$!
8206
8207         for i in {0..100}; do
8208                 # define OBD_FAIL_OSD_TXN_START    0x19a
8209                 local index=$((i % MDSCOUNT + 1))
8210
8211                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8212                         > /dev/null
8213                 sleep 0.01
8214         done
8215
8216         kill -9 $pid
8217
8218         for i in $(seq $MDSCOUNT); do
8219                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8220         done
8221
8222         mkdir $DIR/$tdir/new || error "mkdir failed"
8223         rmdir $DIR/$tdir/new || error "rmdir failed"
8224
8225         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8226                 -t namespace
8227         for i in $(seq $MDSCOUNT); do
8228                 wait_update_facet mds$i "$LCTL get_param -n \
8229                         mdd.$(facet_svc mds$i).lfsck_namespace |
8230                         awk '/^status/ { print \\\$2 }'" "completed"
8231         done
8232
8233         ls -R $DIR/$tdir || error "ls failed"
8234         rm -rf $DIR/$tdir || error "rmdir failed"
8235 }
8236 run_test 60g "transaction abort won't cause MDT hung"
8237
8238 test_60h() {
8239         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8240                 skip "Need MDS version at least 2.12.52"
8241         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8242
8243         local f
8244
8245         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8246         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8247         for fail_loc in 0x80000188 0x80000189; do
8248                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8249                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8250                         error "mkdir $dir-$fail_loc failed"
8251                 for i in {0..10}; do
8252                         # create may fail on missing stripe
8253                         echo $i > $DIR/$tdir-$fail_loc/$i
8254                 done
8255                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8256                         error "getdirstripe $tdir-$fail_loc failed"
8257                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8258                         error "migrate $tdir-$fail_loc failed"
8259                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8260                         error "getdirstripe $tdir-$fail_loc failed"
8261                 pushd $DIR/$tdir-$fail_loc
8262                 for f in *; do
8263                         echo $f | cmp $f - || error "$f data mismatch"
8264                 done
8265                 popd
8266                 rm -rf $DIR/$tdir-$fail_loc
8267         done
8268 }
8269 run_test 60h "striped directory with missing stripes can be accessed"
8270
8271 test_61a() {
8272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8273
8274         f="$DIR/f61"
8275         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8276         cancel_lru_locks osc
8277         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8278         sync
8279 }
8280 run_test 61a "mmap() writes don't make sync hang ================"
8281
8282 test_61b() {
8283         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8284 }
8285 run_test 61b "mmap() of unstriped file is successful"
8286
8287 # bug 2330 - insufficient obd_match error checking causes LBUG
8288 test_62() {
8289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8290
8291         f="$DIR/f62"
8292         echo foo > $f
8293         cancel_lru_locks osc
8294         lctl set_param fail_loc=0x405
8295         cat $f && error "cat succeeded, expect -EIO"
8296         lctl set_param fail_loc=0
8297 }
8298 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8299 # match every page all of the time.
8300 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8301
8302 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8303 # Though this test is irrelevant anymore, it helped to reveal some
8304 # other grant bugs (LU-4482), let's keep it.
8305 test_63a() {   # was test_63
8306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8307
8308         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8309
8310         for i in `seq 10` ; do
8311                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8312                 sleep 5
8313                 kill $!
8314                 sleep 1
8315         done
8316
8317         rm -f $DIR/f63 || true
8318 }
8319 run_test 63a "Verify oig_wait interruption does not crash ======="
8320
8321 # bug 2248 - async write errors didn't return to application on sync
8322 # bug 3677 - async write errors left page locked
8323 test_63b() {
8324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8325
8326         debugsave
8327         lctl set_param debug=-1
8328
8329         # ensure we have a grant to do async writes
8330         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8331         rm $DIR/$tfile
8332
8333         sync    # sync lest earlier test intercept the fail_loc
8334
8335         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8336         lctl set_param fail_loc=0x80000406
8337         $MULTIOP $DIR/$tfile Owy && \
8338                 error "sync didn't return ENOMEM"
8339         sync; sleep 2; sync     # do a real sync this time to flush page
8340         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8341                 error "locked page left in cache after async error" || true
8342         debugrestore
8343 }
8344 run_test 63b "async write errors should be returned to fsync ==="
8345
8346 test_64a () {
8347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8348
8349         lfs df $DIR
8350         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8351 }
8352 run_test 64a "verify filter grant calculations (in kernel) ====="
8353
8354 test_64b () {
8355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8356
8357         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8358 }
8359 run_test 64b "check out-of-space detection on client"
8360
8361 test_64c() {
8362         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8363 }
8364 run_test 64c "verify grant shrink"
8365
8366 import_param() {
8367         local tgt=$1
8368         local param=$2
8369
8370         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8371 }
8372
8373 # this does exactly what osc_request.c:osc_announce_cached() does in
8374 # order to calculate max amount of grants to ask from server
8375 want_grant() {
8376         local tgt=$1
8377
8378         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8379         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8380
8381         ((rpc_in_flight++));
8382         nrpages=$((nrpages * rpc_in_flight))
8383
8384         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8385
8386         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8387
8388         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8389         local undirty=$((nrpages * PAGE_SIZE))
8390
8391         local max_extent_pages
8392         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8393         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8394         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8395         local grant_extent_tax
8396         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8397
8398         undirty=$((undirty + nrextents * grant_extent_tax))
8399
8400         echo $undirty
8401 }
8402
8403 # this is size of unit for grant allocation. It should be equal to
8404 # what tgt_grant.c:tgt_grant_chunk() calculates
8405 grant_chunk() {
8406         local tgt=$1
8407         local max_brw_size
8408         local grant_extent_tax
8409
8410         max_brw_size=$(import_param $tgt max_brw_size)
8411
8412         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8413
8414         echo $(((max_brw_size + grant_extent_tax) * 2))
8415 }
8416
8417 test_64d() {
8418         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8419                 skip "OST < 2.10.55 doesn't limit grants enough"
8420
8421         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8422
8423         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8424                 skip "no grant_param connect flag"
8425
8426         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8427
8428         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8429         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8430
8431
8432         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8433         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8434
8435         $LFS setstripe $DIR/$tfile -i 0 -c 1
8436         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8437         ddpid=$!
8438
8439         while kill -0 $ddpid; do
8440                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8441
8442                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8443                         kill $ddpid
8444                         error "cur_grant $cur_grant > $max_cur_granted"
8445                 fi
8446
8447                 sleep 1
8448         done
8449 }
8450 run_test 64d "check grant limit exceed"
8451
8452 check_grants() {
8453         local tgt=$1
8454         local expected=$2
8455         local msg=$3
8456         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8457
8458         ((cur_grants == expected)) ||
8459                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8460 }
8461
8462 round_up_p2() {
8463         echo $((($1 + $2 - 1) & ~($2 - 1)))
8464 }
8465
8466 test_64e() {
8467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8468         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8469                 skip "Need OSS version at least 2.11.56"
8470
8471         # Remount client to reset grant
8472         remount_client $MOUNT || error "failed to remount client"
8473         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8474
8475         local init_grants=$(import_param $osc_tgt initial_grant)
8476
8477         check_grants $osc_tgt $init_grants "init grants"
8478
8479         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8480         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8481         local gbs=$(import_param $osc_tgt grant_block_size)
8482
8483         # write random number of bytes from max_brw_size / 4 to max_brw_size
8484         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8485         # align for direct io
8486         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8487         # round to grant consumption unit
8488         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8489
8490         local grants=$((wb_round_up + extent_tax))
8491
8492         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8493
8494         # define OBD_FAIL_TGT_NO_GRANT 0x725
8495         # make the server not grant more back
8496         do_facet ost1 $LCTL set_param fail_loc=0x725
8497         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8498
8499         do_facet ost1 $LCTL set_param fail_loc=0
8500
8501         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8502
8503         rm -f $DIR/$tfile || error "rm failed"
8504
8505         # Remount client to reset grant
8506         remount_client $MOUNT || error "failed to remount client"
8507         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8508
8509         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8510
8511         # define OBD_FAIL_TGT_NO_GRANT 0x725
8512         # make the server not grant more back
8513         do_facet ost1 $LCTL set_param fail_loc=0x725
8514         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8515         do_facet ost1 $LCTL set_param fail_loc=0
8516
8517         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8518 }
8519 run_test 64e "check grant consumption (no grant allocation)"
8520
8521 test_64f() {
8522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8523
8524         # Remount client to reset grant
8525         remount_client $MOUNT || error "failed to remount client"
8526         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8527
8528         local init_grants=$(import_param $osc_tgt initial_grant)
8529         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8530         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8531         local gbs=$(import_param $osc_tgt grant_block_size)
8532         local chunk=$(grant_chunk $osc_tgt)
8533
8534         # write random number of bytes from max_brw_size / 4 to max_brw_size
8535         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8536         # align for direct io
8537         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8538         # round to grant consumption unit
8539         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8540
8541         local grants=$((wb_round_up + extent_tax))
8542
8543         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8544         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8545                 error "error writing to $DIR/$tfile"
8546
8547         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8548                 "direct io with grant allocation"
8549
8550         rm -f $DIR/$tfile || error "rm failed"
8551
8552         # Remount client to reset grant
8553         remount_client $MOUNT || error "failed to remount client"
8554         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8555
8556         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8557
8558         local cmd="oO_WRONLY:w${write_bytes}_yc"
8559
8560         $MULTIOP $DIR/$tfile $cmd &
8561         MULTIPID=$!
8562         sleep 1
8563
8564         check_grants $osc_tgt $((init_grants - grants)) \
8565                 "buffered io, not write rpc"
8566
8567         kill -USR1 $MULTIPID
8568         wait
8569
8570         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8571                 "buffered io, one RPC"
8572 }
8573 run_test 64f "check grant consumption (with grant allocation)"
8574
8575 # bug 1414 - set/get directories' stripe info
8576 test_65a() {
8577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8578
8579         test_mkdir $DIR/$tdir
8580         touch $DIR/$tdir/f1
8581         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8582 }
8583 run_test 65a "directory with no stripe info"
8584
8585 test_65b() {
8586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8587
8588         test_mkdir $DIR/$tdir
8589         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8590
8591         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8592                                                 error "setstripe"
8593         touch $DIR/$tdir/f2
8594         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8595 }
8596 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8597
8598 test_65c() {
8599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8600         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8601
8602         test_mkdir $DIR/$tdir
8603         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8604
8605         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8606                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8607         touch $DIR/$tdir/f3
8608         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8609 }
8610 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8611
8612 test_65d() {
8613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8614
8615         test_mkdir $DIR/$tdir
8616         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8617         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8618
8619         if [[ $STRIPECOUNT -le 0 ]]; then
8620                 sc=1
8621         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8622                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8623                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8624         else
8625                 sc=$(($STRIPECOUNT - 1))
8626         fi
8627         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8628         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8629         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8630                 error "lverify failed"
8631 }
8632 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8633
8634 test_65e() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         test_mkdir $DIR/$tdir
8638
8639         $LFS setstripe $DIR/$tdir || error "setstripe"
8640         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8641                                         error "no stripe info failed"
8642         touch $DIR/$tdir/f6
8643         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8644 }
8645 run_test 65e "directory setstripe defaults"
8646
8647 test_65f() {
8648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8649
8650         test_mkdir $DIR/${tdir}f
8651         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8652                 error "setstripe succeeded" || true
8653 }
8654 run_test 65f "dir setstripe permission (should return error) ==="
8655
8656 test_65g() {
8657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8658
8659         test_mkdir $DIR/$tdir
8660         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8661
8662         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8663                 error "setstripe -S failed"
8664         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8665         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8666                 error "delete default stripe failed"
8667 }
8668 run_test 65g "directory setstripe -d"
8669
8670 test_65h() {
8671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8672
8673         test_mkdir $DIR/$tdir
8674         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8675
8676         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8677                 error "setstripe -S failed"
8678         test_mkdir $DIR/$tdir/dd1
8679         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8680                 error "stripe info inherit failed"
8681 }
8682 run_test 65h "directory stripe info inherit ===================="
8683
8684 test_65i() {
8685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8686
8687         save_layout_restore_at_exit $MOUNT
8688
8689         # bug6367: set non-default striping on root directory
8690         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8691
8692         # bug12836: getstripe on -1 default directory striping
8693         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8694
8695         # bug12836: getstripe -v on -1 default directory striping
8696         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8697
8698         # bug12836: new find on -1 default directory striping
8699         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8700 }
8701 run_test 65i "various tests to set root directory striping"
8702
8703 test_65j() { # bug6367
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705
8706         sync; sleep 1
8707
8708         # if we aren't already remounting for each test, do so for this test
8709         if [ "$I_MOUNTED" = "yes" ]; then
8710                 cleanup || error "failed to unmount"
8711                 setup
8712         fi
8713
8714         save_layout_restore_at_exit $MOUNT
8715
8716         $LFS setstripe -d $MOUNT || error "setstripe failed"
8717 }
8718 run_test 65j "set default striping on root directory (bug 6367)="
8719
8720 cleanup_65k() {
8721         rm -rf $DIR/$tdir
8722         wait_delete_completed
8723         do_facet $SINGLEMDS "lctl set_param -n \
8724                 osp.$ost*MDT0000.max_create_count=$max_count"
8725         do_facet $SINGLEMDS "lctl set_param -n \
8726                 osp.$ost*MDT0000.create_count=$count"
8727         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8728         echo $INACTIVE_OSC "is Activate"
8729
8730         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8731 }
8732
8733 test_65k() { # bug11679
8734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8735         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8736         remote_mds_nodsh && skip "remote MDS with nodsh"
8737
8738         local disable_precreate=true
8739         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8740                 disable_precreate=false
8741
8742         echo "Check OST status: "
8743         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8744                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8745
8746         for OSC in $MDS_OSCS; do
8747                 echo $OSC "is active"
8748                 do_facet $SINGLEMDS lctl --device %$OSC activate
8749         done
8750
8751         for INACTIVE_OSC in $MDS_OSCS; do
8752                 local ost=$(osc_to_ost $INACTIVE_OSC)
8753                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8754                                lov.*md*.target_obd |
8755                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8756
8757                 mkdir -p $DIR/$tdir
8758                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8759                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8760
8761                 echo "Deactivate: " $INACTIVE_OSC
8762                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8763
8764                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8765                               osp.$ost*MDT0000.create_count")
8766                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8767                                   osp.$ost*MDT0000.max_create_count")
8768                 $disable_precreate &&
8769                         do_facet $SINGLEMDS "lctl set_param -n \
8770                                 osp.$ost*MDT0000.max_create_count=0"
8771
8772                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8773                         [ -f $DIR/$tdir/$idx ] && continue
8774                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8775                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8776                                 { cleanup_65k;
8777                                   error "setstripe $idx should succeed"; }
8778                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8779                 done
8780                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8781                 rmdir $DIR/$tdir
8782
8783                 do_facet $SINGLEMDS "lctl set_param -n \
8784                         osp.$ost*MDT0000.max_create_count=$max_count"
8785                 do_facet $SINGLEMDS "lctl set_param -n \
8786                         osp.$ost*MDT0000.create_count=$count"
8787                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8788                 echo $INACTIVE_OSC "is Activate"
8789
8790                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8791         done
8792 }
8793 run_test 65k "validate manual striping works properly with deactivated OSCs"
8794
8795 test_65l() { # bug 12836
8796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8797
8798         test_mkdir -p $DIR/$tdir/test_dir
8799         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8800         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8801 }
8802 run_test 65l "lfs find on -1 stripe dir ========================"
8803
8804 test_65m() {
8805         local layout=$(save_layout $MOUNT)
8806         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8807                 restore_layout $MOUNT $layout
8808                 error "setstripe should fail by non-root users"
8809         }
8810         true
8811 }
8812 run_test 65m "normal user can't set filesystem default stripe"
8813
8814 test_65n() {
8815         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8816         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8817                 skip "Need MDS version at least 2.12.50"
8818         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8819
8820         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8821         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8822         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8823
8824         save_layout_restore_at_exit $MOUNT
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 test_160n() {
16086         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16087         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16088                 skip "Need MDS version at least 2.14.51"
16089         local cl_users
16090         local cl_user1
16091         local cl_user2
16092         local pid1
16093         local first_rec
16094         local last_rec=0
16095
16096         # Create a user
16097         changelog_register || error "first changelog_register failed"
16098
16099         cl_users=(${CL_USERS[mds1]})
16100         cl_user1="${cl_users[0]}"
16101
16102         # generate some changelog records to accumulate on MDT0
16103         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16104         first_rec=$(changelog_users $SINGLEMDS |
16105                         awk '/^current.index:/ { print $NF }')
16106         while (( last_rec < (( first_rec + 65000)) )); do
16107                 createmany -m $DIR/$tdir/$tfile 10000 ||
16108                         error "create $DIR/$tdir/$tfile failed"
16109
16110                 for i in $(seq 0 10000); do
16111                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16112                                 > /dev/null
16113                 done
16114
16115                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16116                         error "unlinkmany failed unlink"
16117                 last_rec=$(changelog_users $SINGLEMDS |
16118                         awk '/^current.index:/ { print $NF }')
16119                 echo last record $last_rec
16120                 (( last_rec == 0 )) && error "no changelog found"
16121         done
16122
16123 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16124         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16125
16126         __changelog_clear mds1 $cl_user1 0 &
16127         pid1=$!
16128         sleep 2
16129         __changelog_clear mds1 $cl_user1 0 ||
16130                 error "fail to cancel record for $cl_user1"
16131         wait $pid1
16132         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16133 }
16134 run_test 160n "Changelog destroy race"
16135
16136 test_161a() {
16137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16138
16139         test_mkdir -c1 $DIR/$tdir
16140         cp /etc/hosts $DIR/$tdir/$tfile
16141         test_mkdir -c1 $DIR/$tdir/foo1
16142         test_mkdir -c1 $DIR/$tdir/foo2
16143         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16144         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16145         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16146         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16147         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16148         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16149                 $LFS fid2path $DIR $FID
16150                 error "bad link ea"
16151         fi
16152         # middle
16153         rm $DIR/$tdir/foo2/zachary
16154         # last
16155         rm $DIR/$tdir/foo2/thor
16156         # first
16157         rm $DIR/$tdir/$tfile
16158         # rename
16159         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16160         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16161                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16162         rm $DIR/$tdir/foo2/maggie
16163
16164         # overflow the EA
16165         local longname=$tfile.avg_len_is_thirty_two_
16166         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16167                 error_noexit 'failed to unlink many hardlinks'" EXIT
16168         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/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 ]] || error "expected at least 60 links in link EA"
16173 }
16174 run_test 161a "link ea sanity"
16175
16176 test_161b() {
16177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16178         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16179
16180         local MDTIDX=1
16181         local remote_dir=$DIR/$tdir/remote_dir
16182
16183         mkdir -p $DIR/$tdir
16184         $LFS mkdir -i $MDTIDX $remote_dir ||
16185                 error "create remote directory failed"
16186
16187         cp /etc/hosts $remote_dir/$tfile
16188         mkdir -p $remote_dir/foo1
16189         mkdir -p $remote_dir/foo2
16190         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16191         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16192         ln $remote_dir/$tfile $remote_dir/foo1/luna
16193         ln $remote_dir/$tfile $remote_dir/foo2/thor
16194
16195         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16196                      tr -d ']')
16197         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16198                 $LFS fid2path $DIR $FID
16199                 error "bad link ea"
16200         fi
16201         # middle
16202         rm $remote_dir/foo2/zachary
16203         # last
16204         rm $remote_dir/foo2/thor
16205         # first
16206         rm $remote_dir/$tfile
16207         # rename
16208         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16209         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16210         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16211                 $LFS fid2path $DIR $FID
16212                 error "bad link rename"
16213         fi
16214         rm $remote_dir/foo2/maggie
16215
16216         # overflow the EA
16217         local longname=filename_avg_len_is_thirty_two_
16218         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16219                 error "failed to hardlink many files"
16220         links=$($LFS fid2path $DIR $FID | wc -l)
16221         echo -n "${links}/1000 links in link EA"
16222         [[ ${links} -gt 60 ]] ||
16223                 error "expected at least 60 links in link EA"
16224         unlinkmany $remote_dir/foo2/$longname 1000 ||
16225         error "failed to unlink many hardlinks"
16226 }
16227 run_test 161b "link ea sanity under remote directory"
16228
16229 test_161c() {
16230         remote_mds_nodsh && skip "remote MDS with nodsh"
16231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16232         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16233                 skip "Need MDS version at least 2.1.5"
16234
16235         # define CLF_RENAME_LAST 0x0001
16236         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16237         changelog_register || error "changelog_register failed"
16238
16239         rm -rf $DIR/$tdir
16240         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16241         touch $DIR/$tdir/foo_161c
16242         touch $DIR/$tdir/bar_161c
16243         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16244         changelog_dump | grep RENME | tail -n 5
16245         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16246         changelog_clear 0 || error "changelog_clear failed"
16247         if [ x$flags != "x0x1" ]; then
16248                 error "flag $flags is not 0x1"
16249         fi
16250
16251         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16252         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16253         touch $DIR/$tdir/foo_161c
16254         touch $DIR/$tdir/bar_161c
16255         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16256         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16257         changelog_dump | grep RENME | tail -n 5
16258         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16259         changelog_clear 0 || error "changelog_clear failed"
16260         if [ x$flags != "x0x0" ]; then
16261                 error "flag $flags is not 0x0"
16262         fi
16263         echo "rename overwrite a target having nlink > 1," \
16264                 "changelog record has flags of $flags"
16265
16266         # rename doesn't overwrite a target (changelog flag 0x0)
16267         touch $DIR/$tdir/foo_161c
16268         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16269         changelog_dump | grep RENME | tail -n 5
16270         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16271         changelog_clear 0 || error "changelog_clear failed"
16272         if [ x$flags != "x0x0" ]; then
16273                 error "flag $flags is not 0x0"
16274         fi
16275         echo "rename doesn't overwrite a target," \
16276                 "changelog record has flags of $flags"
16277
16278         # define CLF_UNLINK_LAST 0x0001
16279         # unlink a file having nlink = 1 (changelog flag 0x1)
16280         rm -f $DIR/$tdir/foo2_161c
16281         changelog_dump | grep UNLNK | tail -n 5
16282         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16283         changelog_clear 0 || error "changelog_clear failed"
16284         if [ x$flags != "x0x1" ]; then
16285                 error "flag $flags is not 0x1"
16286         fi
16287         echo "unlink a file having nlink = 1," \
16288                 "changelog record has flags of $flags"
16289
16290         # unlink a file having nlink > 1 (changelog flag 0x0)
16291         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16292         rm -f $DIR/$tdir/foobar_161c
16293         changelog_dump | grep UNLNK | tail -n 5
16294         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16295         changelog_clear 0 || error "changelog_clear failed"
16296         if [ x$flags != "x0x0" ]; then
16297                 error "flag $flags is not 0x0"
16298         fi
16299         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16300 }
16301 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16302
16303 test_161d() {
16304         remote_mds_nodsh && skip "remote MDS with nodsh"
16305         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16306
16307         local pid
16308         local fid
16309
16310         changelog_register || error "changelog_register failed"
16311
16312         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16313         # interfer with $MOUNT/.lustre/fid/ access
16314         mkdir $DIR/$tdir
16315         [[ $? -eq 0 ]] || error "mkdir failed"
16316
16317         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16318         $LCTL set_param fail_loc=0x8000140c
16319         # 5s pause
16320         $LCTL set_param fail_val=5
16321
16322         # create file
16323         echo foofoo > $DIR/$tdir/$tfile &
16324         pid=$!
16325
16326         # wait for create to be delayed
16327         sleep 2
16328
16329         ps -p $pid
16330         [[ $? -eq 0 ]] || error "create should be blocked"
16331
16332         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16333         stack_trap "rm -f $tempfile"
16334         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16335         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16336         # some delay may occur during ChangeLog publishing and file read just
16337         # above, that could allow file write to happen finally
16338         [[ -s $tempfile ]] && echo "file should be empty"
16339
16340         $LCTL set_param fail_loc=0
16341
16342         wait $pid
16343         [[ $? -eq 0 ]] || error "create failed"
16344 }
16345 run_test 161d "create with concurrent .lustre/fid access"
16346
16347 check_path() {
16348         local expected="$1"
16349         shift
16350         local fid="$2"
16351
16352         local path
16353         path=$($LFS fid2path "$@")
16354         local rc=$?
16355
16356         if [ $rc -ne 0 ]; then
16357                 error "path looked up of '$expected' failed: rc=$rc"
16358         elif [ "$path" != "$expected" ]; then
16359                 error "path looked up '$path' instead of '$expected'"
16360         else
16361                 echo "FID '$fid' resolves to path '$path' as expected"
16362         fi
16363 }
16364
16365 test_162a() { # was test_162
16366         test_mkdir -p -c1 $DIR/$tdir/d2
16367         touch $DIR/$tdir/d2/$tfile
16368         touch $DIR/$tdir/d2/x1
16369         touch $DIR/$tdir/d2/x2
16370         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16371         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16372         # regular file
16373         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16374         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16375
16376         # softlink
16377         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16378         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16379         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16380
16381         # softlink to wrong file
16382         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16383         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16384         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16385
16386         # hardlink
16387         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16388         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16389         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16390         # fid2path dir/fsname should both work
16391         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16392         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16393
16394         # hardlink count: check that there are 2 links
16395         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16396         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16397
16398         # hardlink indexing: remove the first link
16399         rm $DIR/$tdir/d2/p/q/r/hlink
16400         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16401 }
16402 run_test 162a "path lookup sanity"
16403
16404 test_162b() {
16405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16407
16408         mkdir $DIR/$tdir
16409         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16410                                 error "create striped dir failed"
16411
16412         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16413                                         tail -n 1 | awk '{print $2}')
16414         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16415
16416         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16417         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16418
16419         # regular file
16420         for ((i=0;i<5;i++)); do
16421                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16422                         error "get fid for f$i failed"
16423                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16424
16425                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16426                         error "get fid for d$i failed"
16427                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16428         done
16429
16430         return 0
16431 }
16432 run_test 162b "striped directory path lookup sanity"
16433
16434 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16435 test_162c() {
16436         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16437                 skip "Need MDS version at least 2.7.51"
16438
16439         local lpath=$tdir.local
16440         local rpath=$tdir.remote
16441
16442         test_mkdir $DIR/$lpath
16443         test_mkdir $DIR/$rpath
16444
16445         for ((i = 0; i <= 101; i++)); do
16446                 lpath="$lpath/$i"
16447                 mkdir $DIR/$lpath
16448                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16449                         error "get fid for local directory $DIR/$lpath failed"
16450                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16451
16452                 rpath="$rpath/$i"
16453                 test_mkdir $DIR/$rpath
16454                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16455                         error "get fid for remote directory $DIR/$rpath failed"
16456                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16457         done
16458
16459         return 0
16460 }
16461 run_test 162c "fid2path works with paths 100 or more directories deep"
16462
16463 oalr_event_count() {
16464         local event="${1}"
16465         local trace="${2}"
16466
16467         awk -v name="${FSNAME}-OST0000" \
16468             -v event="${event}" \
16469             '$1 == "TRACE" && $2 == event && $3 == name' \
16470             "${trace}" |
16471         wc -l
16472 }
16473
16474 oalr_expect_event_count() {
16475         local event="${1}"
16476         local trace="${2}"
16477         local expect="${3}"
16478         local count
16479
16480         count=$(oalr_event_count "${event}" "${trace}")
16481         if ((count == expect)); then
16482                 return 0
16483         fi
16484
16485         error_noexit "${event} event count was '${count}', expected ${expect}"
16486         cat "${trace}" >&2
16487         exit 1
16488 }
16489
16490 cleanup_165() {
16491         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16492         stop ost1
16493         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16494 }
16495
16496 setup_165() {
16497         sync # Flush previous IOs so we can count log entries.
16498         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16499         stack_trap cleanup_165 EXIT
16500 }
16501
16502 test_165a() {
16503         local trace="/tmp/${tfile}.trace"
16504         local rc
16505         local count
16506
16507         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16508                 skip "OFD access log unsupported"
16509
16510         setup_165
16511         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16512         sleep 5
16513
16514         do_facet ost1 ofd_access_log_reader --list
16515         stop ost1
16516
16517         do_facet ost1 killall -TERM ofd_access_log_reader
16518         wait
16519         rc=$?
16520
16521         if ((rc != 0)); then
16522                 error "ofd_access_log_reader exited with rc = '${rc}'"
16523         fi
16524
16525         # Parse trace file for discovery events:
16526         oalr_expect_event_count alr_log_add "${trace}" 1
16527         oalr_expect_event_count alr_log_eof "${trace}" 1
16528         oalr_expect_event_count alr_log_free "${trace}" 1
16529 }
16530 run_test 165a "ofd access log discovery"
16531
16532 test_165b() {
16533         local trace="/tmp/${tfile}.trace"
16534         local file="${DIR}/${tfile}"
16535         local pfid1
16536         local pfid2
16537         local -a entry
16538         local rc
16539         local count
16540         local size
16541         local flags
16542
16543         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16544                 skip "OFD access log unsupported"
16545
16546         setup_165
16547         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16548         sleep 5
16549
16550         do_facet ost1 ofd_access_log_reader --list
16551
16552         lfs setstripe -c 1 -i 0 "${file}"
16553         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16554                 error "cannot create '${file}'"
16555
16556         sleep 5
16557         do_facet ost1 killall -TERM ofd_access_log_reader
16558         wait
16559         rc=$?
16560
16561         if ((rc != 0)); then
16562                 error "ofd_access_log_reader exited with rc = '${rc}'"
16563         fi
16564
16565         oalr_expect_event_count alr_log_entry "${trace}" 1
16566
16567         pfid1=$($LFS path2fid "${file}")
16568
16569         # 1     2             3   4    5     6   7    8    9     10
16570         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16571         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16572
16573         echo "entry = '${entry[*]}'" >&2
16574
16575         pfid2=${entry[4]}
16576         if [[ "${pfid1}" != "${pfid2}" ]]; then
16577                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16578         fi
16579
16580         size=${entry[8]}
16581         if ((size != 1048576)); then
16582                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16583         fi
16584
16585         flags=${entry[10]}
16586         if [[ "${flags}" != "w" ]]; then
16587                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16588         fi
16589
16590         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16591         sleep 5
16592
16593         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16594                 error "cannot read '${file}'"
16595         sleep 5
16596
16597         do_facet ost1 killall -TERM ofd_access_log_reader
16598         wait
16599         rc=$?
16600
16601         if ((rc != 0)); then
16602                 error "ofd_access_log_reader exited with rc = '${rc}'"
16603         fi
16604
16605         oalr_expect_event_count alr_log_entry "${trace}" 1
16606
16607         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16608         echo "entry = '${entry[*]}'" >&2
16609
16610         pfid2=${entry[4]}
16611         if [[ "${pfid1}" != "${pfid2}" ]]; then
16612                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16613         fi
16614
16615         size=${entry[8]}
16616         if ((size != 524288)); then
16617                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16618         fi
16619
16620         flags=${entry[10]}
16621         if [[ "${flags}" != "r" ]]; then
16622                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16623         fi
16624 }
16625 run_test 165b "ofd access log entries are produced and consumed"
16626
16627 test_165c() {
16628         local trace="/tmp/${tfile}.trace"
16629         local file="${DIR}/${tdir}/${tfile}"
16630
16631         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16632                 skip "OFD access log unsupported"
16633
16634         test_mkdir "${DIR}/${tdir}"
16635
16636         setup_165
16637         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16638         sleep 5
16639
16640         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16641
16642         # 4096 / 64 = 64. Create twice as many entries.
16643         for ((i = 0; i < 128; i++)); do
16644                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16645                         error "cannot create file"
16646         done
16647
16648         sync
16649
16650         do_facet ost1 killall -TERM ofd_access_log_reader
16651         wait
16652         rc=$?
16653         if ((rc != 0)); then
16654                 error "ofd_access_log_reader exited with rc = '${rc}'"
16655         fi
16656
16657         unlinkmany  "${file}-%d" 128
16658 }
16659 run_test 165c "full ofd access logs do not block IOs"
16660
16661 oal_get_read_count() {
16662         local stats="$1"
16663
16664         # STATS lustre-OST0001 alr_read_count 1
16665
16666         do_facet ost1 cat "${stats}" |
16667         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16668              END { print count; }'
16669 }
16670
16671 oal_expect_read_count() {
16672         local stats="$1"
16673         local count
16674         local expect="$2"
16675
16676         # Ask ofd_access_log_reader to write stats.
16677         do_facet ost1 killall -USR1 ofd_access_log_reader
16678
16679         # Allow some time for things to happen.
16680         sleep 1
16681
16682         count=$(oal_get_read_count "${stats}")
16683         if ((count == expect)); then
16684                 return 0
16685         fi
16686
16687         error_noexit "bad read count, got ${count}, expected ${expect}"
16688         do_facet ost1 cat "${stats}" >&2
16689         exit 1
16690 }
16691
16692 test_165d() {
16693         local stats="/tmp/${tfile}.stats"
16694         local file="${DIR}/${tdir}/${tfile}"
16695         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16696
16697         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16698                 skip "OFD access log unsupported"
16699
16700         test_mkdir "${DIR}/${tdir}"
16701
16702         setup_165
16703         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16704         sleep 5
16705
16706         lfs setstripe -c 1 -i 0 "${file}"
16707
16708         do_facet ost1 lctl set_param "${param}=rw"
16709         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16710                 error "cannot create '${file}'"
16711         oal_expect_read_count "${stats}" 1
16712
16713         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16714                 error "cannot read '${file}'"
16715         oal_expect_read_count "${stats}" 2
16716
16717         do_facet ost1 lctl set_param "${param}=r"
16718         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16719                 error "cannot create '${file}'"
16720         oal_expect_read_count "${stats}" 2
16721
16722         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16723                 error "cannot read '${file}'"
16724         oal_expect_read_count "${stats}" 3
16725
16726         do_facet ost1 lctl set_param "${param}=w"
16727         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16728                 error "cannot create '${file}'"
16729         oal_expect_read_count "${stats}" 4
16730
16731         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16732                 error "cannot read '${file}'"
16733         oal_expect_read_count "${stats}" 4
16734
16735         do_facet ost1 lctl set_param "${param}=0"
16736         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16737                 error "cannot create '${file}'"
16738         oal_expect_read_count "${stats}" 4
16739
16740         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16741                 error "cannot read '${file}'"
16742         oal_expect_read_count "${stats}" 4
16743
16744         do_facet ost1 killall -TERM ofd_access_log_reader
16745         wait
16746         rc=$?
16747         if ((rc != 0)); then
16748                 error "ofd_access_log_reader exited with rc = '${rc}'"
16749         fi
16750 }
16751 run_test 165d "ofd_access_log mask works"
16752
16753 test_165e() {
16754         local stats="/tmp/${tfile}.stats"
16755         local file0="${DIR}/${tdir}-0/${tfile}"
16756         local file1="${DIR}/${tdir}-1/${tfile}"
16757
16758         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16759                 skip "OFD access log unsupported"
16760
16761         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16762
16763         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16764         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16765
16766         lfs setstripe -c 1 -i 0 "${file0}"
16767         lfs setstripe -c 1 -i 0 "${file1}"
16768
16769         setup_165
16770         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16771         sleep 5
16772
16773         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16774                 error "cannot create '${file0}'"
16775         sync
16776         oal_expect_read_count "${stats}" 0
16777
16778         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16779                 error "cannot create '${file1}'"
16780         sync
16781         oal_expect_read_count "${stats}" 1
16782
16783         do_facet ost1 killall -TERM ofd_access_log_reader
16784         wait
16785         rc=$?
16786         if ((rc != 0)); then
16787                 error "ofd_access_log_reader exited with rc = '${rc}'"
16788         fi
16789 }
16790 run_test 165e "ofd_access_log MDT index filter works"
16791
16792 test_165f() {
16793         local trace="/tmp/${tfile}.trace"
16794         local rc
16795         local count
16796
16797         setup_165
16798         do_facet ost1 timeout 60 ofd_access_log_reader \
16799                 --exit-on-close --debug=- --trace=- > "${trace}" &
16800         sleep 5
16801         stop ost1
16802
16803         wait
16804         rc=$?
16805
16806         if ((rc != 0)); then
16807                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16808                 cat "${trace}"
16809                 exit 1
16810         fi
16811 }
16812 run_test 165f "ofd_access_log_reader --exit-on-close works"
16813
16814 test_169() {
16815         # do directio so as not to populate the page cache
16816         log "creating a 10 Mb file"
16817         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16818                 error "multiop failed while creating a file"
16819         log "starting reads"
16820         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16821         log "truncating the file"
16822         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16823                 error "multiop failed while truncating the file"
16824         log "killing dd"
16825         kill %+ || true # reads might have finished
16826         echo "wait until dd is finished"
16827         wait
16828         log "removing the temporary file"
16829         rm -rf $DIR/$tfile || error "tmp file removal failed"
16830 }
16831 run_test 169 "parallel read and truncate should not deadlock"
16832
16833 test_170() {
16834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16835
16836         $LCTL clear     # bug 18514
16837         $LCTL debug_daemon start $TMP/${tfile}_log_good
16838         touch $DIR/$tfile
16839         $LCTL debug_daemon stop
16840         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16841                 error "sed failed to read log_good"
16842
16843         $LCTL debug_daemon start $TMP/${tfile}_log_good
16844         rm -rf $DIR/$tfile
16845         $LCTL debug_daemon stop
16846
16847         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16848                error "lctl df log_bad failed"
16849
16850         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16851         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16852
16853         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16854         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16855
16856         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16857                 error "bad_line good_line1 good_line2 are empty"
16858
16859         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16860         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16861         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16862
16863         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16864         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16865         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16866
16867         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16868                 error "bad_line_new good_line_new are empty"
16869
16870         local expected_good=$((good_line1 + good_line2*2))
16871
16872         rm -f $TMP/${tfile}*
16873         # LU-231, short malformed line may not be counted into bad lines
16874         if [ $bad_line -ne $bad_line_new ] &&
16875                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16876                 error "expected $bad_line bad lines, but got $bad_line_new"
16877                 return 1
16878         fi
16879
16880         if [ $expected_good -ne $good_line_new ]; then
16881                 error "expected $expected_good good lines, but got $good_line_new"
16882                 return 2
16883         fi
16884         true
16885 }
16886 run_test 170 "test lctl df to handle corrupted log ====================="
16887
16888 test_171() { # bug20592
16889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16890
16891         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16892         $LCTL set_param fail_loc=0x50e
16893         $LCTL set_param fail_val=3000
16894         multiop_bg_pause $DIR/$tfile O_s || true
16895         local MULTIPID=$!
16896         kill -USR1 $MULTIPID
16897         # cause log dump
16898         sleep 3
16899         wait $MULTIPID
16900         if dmesg | grep "recursive fault"; then
16901                 error "caught a recursive fault"
16902         fi
16903         $LCTL set_param fail_loc=0
16904         true
16905 }
16906 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16907
16908 # it would be good to share it with obdfilter-survey/iokit-libecho code
16909 setup_obdecho_osc () {
16910         local rc=0
16911         local ost_nid=$1
16912         local obdfilter_name=$2
16913         echo "Creating new osc for $obdfilter_name on $ost_nid"
16914         # make sure we can find loopback nid
16915         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16916
16917         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16918                            ${obdfilter_name}_osc_UUID || rc=2; }
16919         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16920                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16921         return $rc
16922 }
16923
16924 cleanup_obdecho_osc () {
16925         local obdfilter_name=$1
16926         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16927         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16928         return 0
16929 }
16930
16931 obdecho_test() {
16932         local OBD=$1
16933         local node=$2
16934         local pages=${3:-64}
16935         local rc=0
16936         local id
16937
16938         local count=10
16939         local obd_size=$(get_obd_size $node $OBD)
16940         local page_size=$(get_page_size $node)
16941         if [[ -n "$obd_size" ]]; then
16942                 local new_count=$((obd_size / (pages * page_size / 1024)))
16943                 [[ $new_count -ge $count ]] || count=$new_count
16944         fi
16945
16946         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16947         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16948                            rc=2; }
16949         if [ $rc -eq 0 ]; then
16950             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16951             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16952         fi
16953         echo "New object id is $id"
16954         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16955                            rc=4; }
16956         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16957                            "test_brw $count w v $pages $id" || rc=4; }
16958         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16959                            rc=4; }
16960         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16961                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16962         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16963                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16964         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16965         return $rc
16966 }
16967
16968 test_180a() {
16969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16970
16971         if ! [ -d /sys/fs/lustre/echo_client ] &&
16972            ! module_loaded obdecho; then
16973                 load_module obdecho/obdecho &&
16974                         stack_trap "rmmod obdecho" EXIT ||
16975                         error "unable to load obdecho on client"
16976         fi
16977
16978         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16979         local host=$($LCTL get_param -n osc.$osc.import |
16980                      awk '/current_connection:/ { print $2 }' )
16981         local target=$($LCTL get_param -n osc.$osc.import |
16982                        awk '/target:/ { print $2 }' )
16983         target=${target%_UUID}
16984
16985         if [ -n "$target" ]; then
16986                 setup_obdecho_osc $host $target &&
16987                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16988                         { error "obdecho setup failed with $?"; return; }
16989
16990                 obdecho_test ${target}_osc client ||
16991                         error "obdecho_test failed on ${target}_osc"
16992         else
16993                 $LCTL get_param osc.$osc.import
16994                 error "there is no osc.$osc.import target"
16995         fi
16996 }
16997 run_test 180a "test obdecho on osc"
16998
16999 test_180b() {
17000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17001         remote_ost_nodsh && skip "remote OST with nodsh"
17002
17003         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17004                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17005                 error "failed to load module obdecho"
17006
17007         local target=$(do_facet ost1 $LCTL dl |
17008                        awk '/obdfilter/ { print $4; exit; }')
17009
17010         if [ -n "$target" ]; then
17011                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17012         else
17013                 do_facet ost1 $LCTL dl
17014                 error "there is no obdfilter target on ost1"
17015         fi
17016 }
17017 run_test 180b "test obdecho directly on obdfilter"
17018
17019 test_180c() { # LU-2598
17020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17021         remote_ost_nodsh && skip "remote OST with nodsh"
17022         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17023                 skip "Need MDS version at least 2.4.0"
17024
17025         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17026                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17027                 error "failed to load module obdecho"
17028
17029         local target=$(do_facet ost1 $LCTL dl |
17030                        awk '/obdfilter/ { print $4; exit; }')
17031
17032         if [ -n "$target" ]; then
17033                 local pages=16384 # 64MB bulk I/O RPC size
17034
17035                 obdecho_test "$target" ost1 "$pages" ||
17036                         error "obdecho_test with pages=$pages failed with $?"
17037         else
17038                 do_facet ost1 $LCTL dl
17039                 error "there is no obdfilter target on ost1"
17040         fi
17041 }
17042 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17043
17044 test_181() { # bug 22177
17045         test_mkdir $DIR/$tdir
17046         # create enough files to index the directory
17047         createmany -o $DIR/$tdir/foobar 4000
17048         # print attributes for debug purpose
17049         lsattr -d .
17050         # open dir
17051         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17052         MULTIPID=$!
17053         # remove the files & current working dir
17054         unlinkmany $DIR/$tdir/foobar 4000
17055         rmdir $DIR/$tdir
17056         kill -USR1 $MULTIPID
17057         wait $MULTIPID
17058         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17059         return 0
17060 }
17061 run_test 181 "Test open-unlinked dir ========================"
17062
17063 test_182() {
17064         local fcount=1000
17065         local tcount=10
17066
17067         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17068
17069         $LCTL set_param mdc.*.rpc_stats=clear
17070
17071         for (( i = 0; i < $tcount; i++ )) ; do
17072                 mkdir $DIR/$tdir/$i
17073         done
17074
17075         for (( i = 0; i < $tcount; i++ )) ; do
17076                 createmany -o $DIR/$tdir/$i/f- $fcount &
17077         done
17078         wait
17079
17080         for (( i = 0; i < $tcount; i++ )) ; do
17081                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17082         done
17083         wait
17084
17085         $LCTL get_param mdc.*.rpc_stats
17086
17087         rm -rf $DIR/$tdir
17088 }
17089 run_test 182 "Test parallel modify metadata operations ================"
17090
17091 test_183() { # LU-2275
17092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17093         remote_mds_nodsh && skip "remote MDS with nodsh"
17094         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17095                 skip "Need MDS version at least 2.3.56"
17096
17097         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17098         echo aaa > $DIR/$tdir/$tfile
17099
17100 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17101         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17102
17103         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17104         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17105
17106         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17107
17108         # Flush negative dentry cache
17109         touch $DIR/$tdir/$tfile
17110
17111         # We are not checking for any leaked references here, they'll
17112         # become evident next time we do cleanup with module unload.
17113         rm -rf $DIR/$tdir
17114 }
17115 run_test 183 "No crash or request leak in case of strange dispositions ========"
17116
17117 # test suite 184 is for LU-2016, LU-2017
17118 test_184a() {
17119         check_swap_layouts_support
17120
17121         dir0=$DIR/$tdir/$testnum
17122         test_mkdir -p -c1 $dir0
17123         ref1=/etc/passwd
17124         ref2=/etc/group
17125         file1=$dir0/f1
17126         file2=$dir0/f2
17127         $LFS setstripe -c1 $file1
17128         cp $ref1 $file1
17129         $LFS setstripe -c2 $file2
17130         cp $ref2 $file2
17131         gen1=$($LFS getstripe -g $file1)
17132         gen2=$($LFS getstripe -g $file2)
17133
17134         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17135         gen=$($LFS getstripe -g $file1)
17136         [[ $gen1 != $gen ]] ||
17137                 "Layout generation on $file1 does not change"
17138         gen=$($LFS getstripe -g $file2)
17139         [[ $gen2 != $gen ]] ||
17140                 "Layout generation on $file2 does not change"
17141
17142         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17143         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17144
17145         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17146 }
17147 run_test 184a "Basic layout swap"
17148
17149 test_184b() {
17150         check_swap_layouts_support
17151
17152         dir0=$DIR/$tdir/$testnum
17153         mkdir -p $dir0 || error "creating dir $dir0"
17154         file1=$dir0/f1
17155         file2=$dir0/f2
17156         file3=$dir0/f3
17157         dir1=$dir0/d1
17158         dir2=$dir0/d2
17159         mkdir $dir1 $dir2
17160         $LFS setstripe -c1 $file1
17161         $LFS setstripe -c2 $file2
17162         $LFS setstripe -c1 $file3
17163         chown $RUNAS_ID $file3
17164         gen1=$($LFS getstripe -g $file1)
17165         gen2=$($LFS getstripe -g $file2)
17166
17167         $LFS swap_layouts $dir1 $dir2 &&
17168                 error "swap of directories layouts should fail"
17169         $LFS swap_layouts $dir1 $file1 &&
17170                 error "swap of directory and file layouts should fail"
17171         $RUNAS $LFS swap_layouts $file1 $file2 &&
17172                 error "swap of file we cannot write should fail"
17173         $LFS swap_layouts $file1 $file3 &&
17174                 error "swap of file with different owner should fail"
17175         /bin/true # to clear error code
17176 }
17177 run_test 184b "Forbidden layout swap (will generate errors)"
17178
17179 test_184c() {
17180         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17181         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17182         check_swap_layouts_support
17183         check_swap_layout_no_dom $DIR
17184
17185         local dir0=$DIR/$tdir/$testnum
17186         mkdir -p $dir0 || error "creating dir $dir0"
17187
17188         local ref1=$dir0/ref1
17189         local ref2=$dir0/ref2
17190         local file1=$dir0/file1
17191         local file2=$dir0/file2
17192         # create a file large enough for the concurrent test
17193         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17194         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17195         echo "ref file size: ref1($(stat -c %s $ref1))," \
17196              "ref2($(stat -c %s $ref2))"
17197
17198         cp $ref2 $file2
17199         dd if=$ref1 of=$file1 bs=16k &
17200         local DD_PID=$!
17201
17202         # Make sure dd starts to copy file, but wait at most 5 seconds
17203         local loops=0
17204         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17205
17206         $LFS swap_layouts $file1 $file2
17207         local rc=$?
17208         wait $DD_PID
17209         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17210         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17211
17212         # how many bytes copied before swapping layout
17213         local copied=$(stat -c %s $file2)
17214         local remaining=$(stat -c %s $ref1)
17215         remaining=$((remaining - copied))
17216         echo "Copied $copied bytes before swapping layout..."
17217
17218         cmp -n $copied $file1 $ref2 | grep differ &&
17219                 error "Content mismatch [0, $copied) of ref2 and file1"
17220         cmp -n $copied $file2 $ref1 ||
17221                 error "Content mismatch [0, $copied) of ref1 and file2"
17222         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17223                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17224
17225         # clean up
17226         rm -f $ref1 $ref2 $file1 $file2
17227 }
17228 run_test 184c "Concurrent write and layout swap"
17229
17230 test_184d() {
17231         check_swap_layouts_support
17232         check_swap_layout_no_dom $DIR
17233         [ -z "$(which getfattr 2>/dev/null)" ] &&
17234                 skip_env "no getfattr command"
17235
17236         local file1=$DIR/$tdir/$tfile-1
17237         local file2=$DIR/$tdir/$tfile-2
17238         local file3=$DIR/$tdir/$tfile-3
17239         local lovea1
17240         local lovea2
17241
17242         mkdir -p $DIR/$tdir
17243         touch $file1 || error "create $file1 failed"
17244         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17245                 error "create $file2 failed"
17246         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17247                 error "create $file3 failed"
17248         lovea1=$(get_layout_param $file1)
17249
17250         $LFS swap_layouts $file2 $file3 ||
17251                 error "swap $file2 $file3 layouts failed"
17252         $LFS swap_layouts $file1 $file2 ||
17253                 error "swap $file1 $file2 layouts failed"
17254
17255         lovea2=$(get_layout_param $file2)
17256         echo "$lovea1"
17257         echo "$lovea2"
17258         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17259
17260         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17261         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17262 }
17263 run_test 184d "allow stripeless layouts swap"
17264
17265 test_184e() {
17266         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17267                 skip "Need MDS version at least 2.6.94"
17268         check_swap_layouts_support
17269         check_swap_layout_no_dom $DIR
17270         [ -z "$(which getfattr 2>/dev/null)" ] &&
17271                 skip_env "no getfattr command"
17272
17273         local file1=$DIR/$tdir/$tfile-1
17274         local file2=$DIR/$tdir/$tfile-2
17275         local file3=$DIR/$tdir/$tfile-3
17276         local lovea
17277
17278         mkdir -p $DIR/$tdir
17279         touch $file1 || error "create $file1 failed"
17280         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17281                 error "create $file2 failed"
17282         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17283                 error "create $file3 failed"
17284
17285         $LFS swap_layouts $file1 $file2 ||
17286                 error "swap $file1 $file2 layouts failed"
17287
17288         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17289         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17290
17291         echo 123 > $file1 || error "Should be able to write into $file1"
17292
17293         $LFS swap_layouts $file1 $file3 ||
17294                 error "swap $file1 $file3 layouts failed"
17295
17296         echo 123 > $file1 || error "Should be able to write into $file1"
17297
17298         rm -rf $file1 $file2 $file3
17299 }
17300 run_test 184e "Recreate layout after stripeless layout swaps"
17301
17302 test_184f() {
17303         # Create a file with name longer than sizeof(struct stat) ==
17304         # 144 to see if we can get chars from the file name to appear
17305         # in the returned striping. Note that 'f' == 0x66.
17306         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17307
17308         mkdir -p $DIR/$tdir
17309         mcreate $DIR/$tdir/$file
17310         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17311                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17312         fi
17313 }
17314 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17315
17316 test_185() { # LU-2441
17317         # LU-3553 - no volatile file support in old servers
17318         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17319                 skip "Need MDS version at least 2.3.60"
17320
17321         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17322         touch $DIR/$tdir/spoo
17323         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17324         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17325                 error "cannot create/write a volatile file"
17326         [ "$FILESET" == "" ] &&
17327         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17328                 error "FID is still valid after close"
17329
17330         multiop_bg_pause $DIR/$tdir vVw4096_c
17331         local multi_pid=$!
17332
17333         local OLD_IFS=$IFS
17334         IFS=":"
17335         local fidv=($fid)
17336         IFS=$OLD_IFS
17337         # assume that the next FID for this client is sequential, since stdout
17338         # is unfortunately eaten by multiop_bg_pause
17339         local n=$((${fidv[1]} + 1))
17340         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17341         if [ "$FILESET" == "" ]; then
17342                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17343                         error "FID is missing before close"
17344         fi
17345         kill -USR1 $multi_pid
17346         # 1 second delay, so if mtime change we will see it
17347         sleep 1
17348         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17349         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17350 }
17351 run_test 185 "Volatile file support"
17352
17353 function create_check_volatile() {
17354         local idx=$1
17355         local tgt
17356
17357         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17358         local PID=$!
17359         sleep 1
17360         local FID=$(cat /tmp/${tfile}.fid)
17361         [ "$FID" == "" ] && error "can't get FID for volatile"
17362         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17363         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17364         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17365         kill -USR1 $PID
17366         wait
17367         sleep 1
17368         cancel_lru_locks mdc # flush opencache
17369         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17370         return 0
17371 }
17372
17373 test_185a(){
17374         # LU-12516 - volatile creation via .lustre
17375         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17376                 skip "Need MDS version at least 2.3.55"
17377
17378         create_check_volatile 0
17379         [ $MDSCOUNT -lt 2 ] && return 0
17380
17381         # DNE case
17382         create_check_volatile 1
17383
17384         return 0
17385 }
17386 run_test 185a "Volatile file creation in .lustre/fid/"
17387
17388 test_187a() {
17389         remote_mds_nodsh && skip "remote MDS with nodsh"
17390         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17391                 skip "Need MDS version at least 2.3.0"
17392
17393         local dir0=$DIR/$tdir/$testnum
17394         mkdir -p $dir0 || error "creating dir $dir0"
17395
17396         local file=$dir0/file1
17397         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17398         local dv1=$($LFS data_version $file)
17399         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17400         local dv2=$($LFS data_version $file)
17401         [[ $dv1 != $dv2 ]] ||
17402                 error "data version did not change on write $dv1 == $dv2"
17403
17404         # clean up
17405         rm -f $file1
17406 }
17407 run_test 187a "Test data version change"
17408
17409 test_187b() {
17410         remote_mds_nodsh && skip "remote MDS with nodsh"
17411         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17412                 skip "Need MDS version at least 2.3.0"
17413
17414         local dir0=$DIR/$tdir/$testnum
17415         mkdir -p $dir0 || error "creating dir $dir0"
17416
17417         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17418         [[ ${DV[0]} != ${DV[1]} ]] ||
17419                 error "data version did not change on write"\
17420                       " ${DV[0]} == ${DV[1]}"
17421
17422         # clean up
17423         rm -f $file1
17424 }
17425 run_test 187b "Test data version change on volatile file"
17426
17427 test_200() {
17428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17429         remote_mgs_nodsh && skip "remote MGS with nodsh"
17430         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17431
17432         local POOL=${POOL:-cea1}
17433         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17434         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17435         # Pool OST targets
17436         local first_ost=0
17437         local last_ost=$(($OSTCOUNT - 1))
17438         local ost_step=2
17439         local ost_list=$(seq $first_ost $ost_step $last_ost)
17440         local ost_range="$first_ost $last_ost $ost_step"
17441         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17442         local file_dir=$POOL_ROOT/file_tst
17443         local subdir=$test_path/subdir
17444         local rc=0
17445
17446         while : ; do
17447                 # former test_200a test_200b
17448                 pool_add $POOL                          || { rc=$? ; break; }
17449                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17450                 # former test_200c test_200d
17451                 mkdir -p $test_path
17452                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17453                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17454                 mkdir -p $subdir
17455                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17456                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17457                                                         || { rc=$? ; break; }
17458                 # former test_200e test_200f
17459                 local files=$((OSTCOUNT*3))
17460                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17461                                                         || { rc=$? ; break; }
17462                 pool_create_files $POOL $file_dir $files "$ost_list" \
17463                                                         || { rc=$? ; break; }
17464                 # former test_200g test_200h
17465                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17466                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17467
17468                 # former test_201a test_201b test_201c
17469                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17470
17471                 local f=$test_path/$tfile
17472                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17473                 pool_remove $POOL $f                    || { rc=$? ; break; }
17474                 break
17475         done
17476
17477         destroy_test_pools
17478
17479         return $rc
17480 }
17481 run_test 200 "OST pools"
17482
17483 # usage: default_attr <count | size | offset>
17484 default_attr() {
17485         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17486 }
17487
17488 # usage: check_default_stripe_attr
17489 check_default_stripe_attr() {
17490         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17491         case $1 in
17492         --stripe-count|-c)
17493                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17494         --stripe-size|-S)
17495                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17496         --stripe-index|-i)
17497                 EXPECTED=-1;;
17498         *)
17499                 error "unknown getstripe attr '$1'"
17500         esac
17501
17502         [ $ACTUAL == $EXPECTED ] ||
17503                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17504 }
17505
17506 test_204a() {
17507         test_mkdir $DIR/$tdir
17508         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17509
17510         check_default_stripe_attr --stripe-count
17511         check_default_stripe_attr --stripe-size
17512         check_default_stripe_attr --stripe-index
17513 }
17514 run_test 204a "Print default stripe attributes"
17515
17516 test_204b() {
17517         test_mkdir $DIR/$tdir
17518         $LFS setstripe --stripe-count 1 $DIR/$tdir
17519
17520         check_default_stripe_attr --stripe-size
17521         check_default_stripe_attr --stripe-index
17522 }
17523 run_test 204b "Print default stripe size and offset"
17524
17525 test_204c() {
17526         test_mkdir $DIR/$tdir
17527         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17528
17529         check_default_stripe_attr --stripe-count
17530         check_default_stripe_attr --stripe-index
17531 }
17532 run_test 204c "Print default stripe count and offset"
17533
17534 test_204d() {
17535         test_mkdir $DIR/$tdir
17536         $LFS setstripe --stripe-index 0 $DIR/$tdir
17537
17538         check_default_stripe_attr --stripe-count
17539         check_default_stripe_attr --stripe-size
17540 }
17541 run_test 204d "Print default stripe count and size"
17542
17543 test_204e() {
17544         test_mkdir $DIR/$tdir
17545         $LFS setstripe -d $DIR/$tdir
17546
17547         check_default_stripe_attr --stripe-count --raw
17548         check_default_stripe_attr --stripe-size --raw
17549         check_default_stripe_attr --stripe-index --raw
17550 }
17551 run_test 204e "Print raw stripe attributes"
17552
17553 test_204f() {
17554         test_mkdir $DIR/$tdir
17555         $LFS setstripe --stripe-count 1 $DIR/$tdir
17556
17557         check_default_stripe_attr --stripe-size --raw
17558         check_default_stripe_attr --stripe-index --raw
17559 }
17560 run_test 204f "Print raw stripe size and offset"
17561
17562 test_204g() {
17563         test_mkdir $DIR/$tdir
17564         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17565
17566         check_default_stripe_attr --stripe-count --raw
17567         check_default_stripe_attr --stripe-index --raw
17568 }
17569 run_test 204g "Print raw stripe count and offset"
17570
17571 test_204h() {
17572         test_mkdir $DIR/$tdir
17573         $LFS setstripe --stripe-index 0 $DIR/$tdir
17574
17575         check_default_stripe_attr --stripe-count --raw
17576         check_default_stripe_attr --stripe-size --raw
17577 }
17578 run_test 204h "Print raw stripe count and size"
17579
17580 # Figure out which job scheduler is being used, if any,
17581 # or use a fake one
17582 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17583         JOBENV=SLURM_JOB_ID
17584 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17585         JOBENV=LSB_JOBID
17586 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17587         JOBENV=PBS_JOBID
17588 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17589         JOBENV=LOADL_STEP_ID
17590 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17591         JOBENV=JOB_ID
17592 else
17593         $LCTL list_param jobid_name > /dev/null 2>&1
17594         if [ $? -eq 0 ]; then
17595                 JOBENV=nodelocal
17596         else
17597                 JOBENV=FAKE_JOBID
17598         fi
17599 fi
17600 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17601
17602 verify_jobstats() {
17603         local cmd=($1)
17604         shift
17605         local facets="$@"
17606
17607 # we don't really need to clear the stats for this test to work, since each
17608 # command has a unique jobid, but it makes debugging easier if needed.
17609 #       for facet in $facets; do
17610 #               local dev=$(convert_facet2label $facet)
17611 #               # clear old jobstats
17612 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17613 #       done
17614
17615         # use a new JobID for each test, or we might see an old one
17616         [ "$JOBENV" = "FAKE_JOBID" ] &&
17617                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17618
17619         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17620
17621         [ "$JOBENV" = "nodelocal" ] && {
17622                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17623                 $LCTL set_param jobid_name=$FAKE_JOBID
17624                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17625         }
17626
17627         log "Test: ${cmd[*]}"
17628         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17629
17630         if [ $JOBENV = "FAKE_JOBID" ]; then
17631                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17632         else
17633                 ${cmd[*]}
17634         fi
17635
17636         # all files are created on OST0000
17637         for facet in $facets; do
17638                 local stats="*.$(convert_facet2label $facet).job_stats"
17639
17640                 # strip out libtool wrappers for in-tree executables
17641                 if [ $(do_facet $facet lctl get_param $stats |
17642                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17643                         do_facet $facet lctl get_param $stats
17644                         error "No jobstats for $JOBVAL found on $facet::$stats"
17645                 fi
17646         done
17647 }
17648
17649 jobstats_set() {
17650         local new_jobenv=$1
17651
17652         set_persistent_param_and_check client "jobid_var" \
17653                 "$FSNAME.sys.jobid_var" $new_jobenv
17654 }
17655
17656 test_205a() { # Job stats
17657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17658         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17659                 skip "Need MDS version with at least 2.7.1"
17660         remote_mgs_nodsh && skip "remote MGS with nodsh"
17661         remote_mds_nodsh && skip "remote MDS with nodsh"
17662         remote_ost_nodsh && skip "remote OST with nodsh"
17663         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17664                 skip "Server doesn't support jobstats"
17665         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17666
17667         local old_jobenv=$($LCTL get_param -n jobid_var)
17668         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17669
17670         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17671                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17672         else
17673                 stack_trap "do_facet mgs $PERM_CMD \
17674                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17675         fi
17676         changelog_register
17677
17678         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17679                                 mdt.*.job_cleanup_interval | head -n 1)
17680         local new_interval=5
17681         do_facet $SINGLEMDS \
17682                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17683         stack_trap "do_facet $SINGLEMDS \
17684                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17685         local start=$SECONDS
17686
17687         local cmd
17688         # mkdir
17689         cmd="mkdir $DIR/$tdir"
17690         verify_jobstats "$cmd" "$SINGLEMDS"
17691         # rmdir
17692         cmd="rmdir $DIR/$tdir"
17693         verify_jobstats "$cmd" "$SINGLEMDS"
17694         # mkdir on secondary MDT
17695         if [ $MDSCOUNT -gt 1 ]; then
17696                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17697                 verify_jobstats "$cmd" "mds2"
17698         fi
17699         # mknod
17700         cmd="mknod $DIR/$tfile c 1 3"
17701         verify_jobstats "$cmd" "$SINGLEMDS"
17702         # unlink
17703         cmd="rm -f $DIR/$tfile"
17704         verify_jobstats "$cmd" "$SINGLEMDS"
17705         # create all files on OST0000 so verify_jobstats can find OST stats
17706         # open & close
17707         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17708         verify_jobstats "$cmd" "$SINGLEMDS"
17709         # setattr
17710         cmd="touch $DIR/$tfile"
17711         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17712         # write
17713         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17714         verify_jobstats "$cmd" "ost1"
17715         # read
17716         cancel_lru_locks osc
17717         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17718         verify_jobstats "$cmd" "ost1"
17719         # truncate
17720         cmd="$TRUNCATE $DIR/$tfile 0"
17721         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17722         # rename
17723         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17724         verify_jobstats "$cmd" "$SINGLEMDS"
17725         # jobstats expiry - sleep until old stats should be expired
17726         local left=$((new_interval + 5 - (SECONDS - start)))
17727         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17728                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17729                         "0" $left
17730         cmd="mkdir $DIR/$tdir.expire"
17731         verify_jobstats "$cmd" "$SINGLEMDS"
17732         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17733             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17734
17735         # Ensure that jobid are present in changelog (if supported by MDS)
17736         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17737                 changelog_dump | tail -10
17738                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17739                 [ $jobids -eq 9 ] ||
17740                         error "Wrong changelog jobid count $jobids != 9"
17741
17742                 # LU-5862
17743                 JOBENV="disable"
17744                 jobstats_set $JOBENV
17745                 touch $DIR/$tfile
17746                 changelog_dump | grep $tfile
17747                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17748                 [ $jobids -eq 0 ] ||
17749                         error "Unexpected jobids when jobid_var=$JOBENV"
17750         fi
17751
17752         # test '%j' access to environment variable - if supported
17753         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17754                 JOBENV="JOBCOMPLEX"
17755                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17756
17757                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17758         fi
17759
17760         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17761                 JOBENV="JOBCOMPLEX"
17762                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17763
17764                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17765         fi
17766
17767         # test '%j' access to per-session jobid - if supported
17768         if lctl list_param jobid_this_session > /dev/null 2>&1
17769         then
17770                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17771                 lctl set_param jobid_this_session=$USER
17772
17773                 JOBENV="JOBCOMPLEX"
17774                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17775
17776                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17777         fi
17778 }
17779 run_test 205a "Verify job stats"
17780
17781 # LU-13117, LU-13597
17782 test_205b() {
17783         job_stats="mdt.*.job_stats"
17784         $LCTL set_param $job_stats=clear
17785         # Setting jobid_var to USER might not be supported
17786         $LCTL set_param jobid_var=USER || true
17787         $LCTL set_param jobid_name="%e.%u"
17788         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17789         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17790                 grep "job_id:.*foolish" &&
17791                         error "Unexpected jobid found"
17792         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17793                 grep "open:.*min.*max.*sum" ||
17794                         error "wrong job_stats format found"
17795 }
17796 run_test 205b "Verify job stats jobid and output format"
17797
17798 # LU-13733
17799 test_205c() {
17800         $LCTL set_param llite.*.stats=0
17801         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17802         $LCTL get_param llite.*.stats
17803         $LCTL get_param llite.*.stats | grep \
17804                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17805                         error "wrong client stats format found"
17806 }
17807 run_test 205c "Verify client stats format"
17808
17809 # LU-1480, LU-1773 and LU-1657
17810 test_206() {
17811         mkdir -p $DIR/$tdir
17812         $LFS setstripe -c -1 $DIR/$tdir
17813 #define OBD_FAIL_LOV_INIT 0x1403
17814         $LCTL set_param fail_loc=0xa0001403
17815         $LCTL set_param fail_val=1
17816         touch $DIR/$tdir/$tfile || true
17817 }
17818 run_test 206 "fail lov_init_raid0() doesn't lbug"
17819
17820 test_207a() {
17821         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17822         local fsz=`stat -c %s $DIR/$tfile`
17823         cancel_lru_locks mdc
17824
17825         # do not return layout in getattr intent
17826 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17827         $LCTL set_param fail_loc=0x170
17828         local sz=`stat -c %s $DIR/$tfile`
17829
17830         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17831
17832         rm -rf $DIR/$tfile
17833 }
17834 run_test 207a "can refresh layout at glimpse"
17835
17836 test_207b() {
17837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17838         local cksum=`md5sum $DIR/$tfile`
17839         local fsz=`stat -c %s $DIR/$tfile`
17840         cancel_lru_locks mdc
17841         cancel_lru_locks osc
17842
17843         # do not return layout in getattr intent
17844 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17845         $LCTL set_param fail_loc=0x171
17846
17847         # it will refresh layout after the file is opened but before read issues
17848         echo checksum is "$cksum"
17849         echo "$cksum" |md5sum -c --quiet || error "file differs"
17850
17851         rm -rf $DIR/$tfile
17852 }
17853 run_test 207b "can refresh layout at open"
17854
17855 test_208() {
17856         # FIXME: in this test suite, only RD lease is used. This is okay
17857         # for now as only exclusive open is supported. After generic lease
17858         # is done, this test suite should be revised. - Jinshan
17859
17860         remote_mds_nodsh && skip "remote MDS with nodsh"
17861         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17862                 skip "Need MDS version at least 2.4.52"
17863
17864         echo "==== test 1: verify get lease work"
17865         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17866
17867         echo "==== test 2: verify lease can be broken by upcoming open"
17868         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17869         local PID=$!
17870         sleep 1
17871
17872         $MULTIOP $DIR/$tfile oO_RDONLY:c
17873         kill -USR1 $PID && wait $PID || error "break lease error"
17874
17875         echo "==== test 3: verify lease can't be granted if an open already exists"
17876         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17877         local PID=$!
17878         sleep 1
17879
17880         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17881         kill -USR1 $PID && wait $PID || error "open file error"
17882
17883         echo "==== test 4: lease can sustain over recovery"
17884         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17885         PID=$!
17886         sleep 1
17887
17888         fail mds1
17889
17890         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17891
17892         echo "==== test 5: lease broken can't be regained by replay"
17893         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17894         PID=$!
17895         sleep 1
17896
17897         # open file to break lease and then recovery
17898         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17899         fail mds1
17900
17901         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17902
17903         rm -f $DIR/$tfile
17904 }
17905 run_test 208 "Exclusive open"
17906
17907 test_209() {
17908         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17909                 skip_env "must have disp_stripe"
17910
17911         touch $DIR/$tfile
17912         sync; sleep 5; sync;
17913
17914         echo 3 > /proc/sys/vm/drop_caches
17915         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17916                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17917         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17918
17919         # open/close 500 times
17920         for i in $(seq 500); do
17921                 cat $DIR/$tfile
17922         done
17923
17924         echo 3 > /proc/sys/vm/drop_caches
17925         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17926                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17927         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17928
17929         echo "before: $req_before, after: $req_after"
17930         [ $((req_after - req_before)) -ge 300 ] &&
17931                 error "open/close requests are not freed"
17932         return 0
17933 }
17934 run_test 209 "read-only open/close requests should be freed promptly"
17935
17936 test_210() {
17937         local pid
17938
17939         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17940         pid=$!
17941         sleep 1
17942
17943         $LFS getstripe $DIR/$tfile
17944         kill -USR1 $pid
17945         wait $pid || error "multiop failed"
17946
17947         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17948         pid=$!
17949         sleep 1
17950
17951         $LFS getstripe $DIR/$tfile
17952         kill -USR1 $pid
17953         wait $pid || error "multiop failed"
17954 }
17955 run_test 210 "lfs getstripe does not break leases"
17956
17957 test_212() {
17958         size=`date +%s`
17959         size=$((size % 8192 + 1))
17960         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17961         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17962         rm -f $DIR/f212 $DIR/f212.xyz
17963 }
17964 run_test 212 "Sendfile test ============================================"
17965
17966 test_213() {
17967         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17968         cancel_lru_locks osc
17969         lctl set_param fail_loc=0x8000040f
17970         # generate a read lock
17971         cat $DIR/$tfile > /dev/null
17972         # write to the file, it will try to cancel the above read lock.
17973         cat /etc/hosts >> $DIR/$tfile
17974 }
17975 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17976
17977 test_214() { # for bug 20133
17978         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17979         for (( i=0; i < 340; i++ )) ; do
17980                 touch $DIR/$tdir/d214c/a$i
17981         done
17982
17983         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17984         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17985         ls $DIR/d214c || error "ls $DIR/d214c failed"
17986         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17987         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17988 }
17989 run_test 214 "hash-indexed directory test - bug 20133"
17990
17991 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17992 create_lnet_proc_files() {
17993         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17994 }
17995
17996 # counterpart of create_lnet_proc_files
17997 remove_lnet_proc_files() {
17998         rm -f $TMP/lnet_$1.sys
17999 }
18000
18001 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18002 # 3rd arg as regexp for body
18003 check_lnet_proc_stats() {
18004         local l=$(cat "$TMP/lnet_$1" |wc -l)
18005         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18006
18007         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18008 }
18009
18010 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18011 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18012 # optional and can be regexp for 2nd line (lnet.routes case)
18013 check_lnet_proc_entry() {
18014         local blp=2          # blp stands for 'position of 1st line of body'
18015         [ -z "$5" ] || blp=3 # lnet.routes case
18016
18017         local l=$(cat "$TMP/lnet_$1" |wc -l)
18018         # subtracting one from $blp because the body can be empty
18019         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18020
18021         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18022                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18023
18024         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18025                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18026
18027         # bail out if any unexpected line happened
18028         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18029         [ "$?" != 0 ] || error "$2 misformatted"
18030 }
18031
18032 test_215() { # for bugs 18102, 21079, 21517
18033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18034
18035         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18036         local P='[1-9][0-9]*'           # positive numeric
18037         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18038         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18039         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18040         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18041
18042         local L1 # regexp for 1st line
18043         local L2 # regexp for 2nd line (optional)
18044         local BR # regexp for the rest (body)
18045
18046         # lnet.stats should look as 11 space-separated non-negative numerics
18047         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18048         create_lnet_proc_files "stats"
18049         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18050         remove_lnet_proc_files "stats"
18051
18052         # lnet.routes should look like this:
18053         # Routing disabled/enabled
18054         # net hops priority state router
18055         # where net is a string like tcp0, hops > 0, priority >= 0,
18056         # state is up/down,
18057         # router is a string like 192.168.1.1@tcp2
18058         L1="^Routing (disabled|enabled)$"
18059         L2="^net +hops +priority +state +router$"
18060         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18061         create_lnet_proc_files "routes"
18062         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18063         remove_lnet_proc_files "routes"
18064
18065         # lnet.routers should look like this:
18066         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18067         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18068         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18069         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18070         L1="^ref +rtr_ref +alive +router$"
18071         BR="^$P +$P +(up|down) +$NID$"
18072         create_lnet_proc_files "routers"
18073         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18074         remove_lnet_proc_files "routers"
18075
18076         # lnet.peers should look like this:
18077         # nid refs state last max rtr min tx min queue
18078         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18079         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18080         # numeric (0 or >0 or <0), queue >= 0.
18081         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18082         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18083         create_lnet_proc_files "peers"
18084         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18085         remove_lnet_proc_files "peers"
18086
18087         # lnet.buffers  should look like this:
18088         # pages count credits min
18089         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18090         L1="^pages +count +credits +min$"
18091         BR="^ +$N +$N +$I +$I$"
18092         create_lnet_proc_files "buffers"
18093         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18094         remove_lnet_proc_files "buffers"
18095
18096         # lnet.nis should look like this:
18097         # nid status alive refs peer rtr max tx min
18098         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18099         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18100         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18101         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18102         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18103         create_lnet_proc_files "nis"
18104         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18105         remove_lnet_proc_files "nis"
18106
18107         # can we successfully write to lnet.stats?
18108         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18109 }
18110 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18111
18112 test_216() { # bug 20317
18113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18114         remote_ost_nodsh && skip "remote OST with nodsh"
18115
18116         local node
18117         local facets=$(get_facets OST)
18118         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18119
18120         save_lustre_params client "osc.*.contention_seconds" > $p
18121         save_lustre_params $facets \
18122                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18123         save_lustre_params $facets \
18124                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18125         save_lustre_params $facets \
18126                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18127         clear_stats osc.*.osc_stats
18128
18129         # agressive lockless i/o settings
18130         do_nodes $(comma_list $(osts_nodes)) \
18131                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18132                         ldlm.namespaces.filter-*.contended_locks=0 \
18133                         ldlm.namespaces.filter-*.contention_seconds=60"
18134         lctl set_param -n osc.*.contention_seconds=60
18135
18136         $DIRECTIO write $DIR/$tfile 0 10 4096
18137         $CHECKSTAT -s 40960 $DIR/$tfile
18138
18139         # disable lockless i/o
18140         do_nodes $(comma_list $(osts_nodes)) \
18141                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18142                         ldlm.namespaces.filter-*.contended_locks=32 \
18143                         ldlm.namespaces.filter-*.contention_seconds=0"
18144         lctl set_param -n osc.*.contention_seconds=0
18145         clear_stats osc.*.osc_stats
18146
18147         dd if=/dev/zero of=$DIR/$tfile count=0
18148         $CHECKSTAT -s 0 $DIR/$tfile
18149
18150         restore_lustre_params <$p
18151         rm -f $p
18152         rm $DIR/$tfile
18153 }
18154 run_test 216 "check lockless direct write updates file size and kms correctly"
18155
18156 test_217() { # bug 22430
18157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18158
18159         local node
18160         local nid
18161
18162         for node in $(nodes_list); do
18163                 nid=$(host_nids_address $node $NETTYPE)
18164                 if [[ $nid = *-* ]] ; then
18165                         echo "lctl ping $(h2nettype $nid)"
18166                         lctl ping $(h2nettype $nid)
18167                 else
18168                         echo "skipping $node (no hyphen detected)"
18169                 fi
18170         done
18171 }
18172 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18173
18174 test_218() {
18175        # do directio so as not to populate the page cache
18176        log "creating a 10 Mb file"
18177        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18178        log "starting reads"
18179        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18180        log "truncating the file"
18181        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18182        log "killing dd"
18183        kill %+ || true # reads might have finished
18184        echo "wait until dd is finished"
18185        wait
18186        log "removing the temporary file"
18187        rm -rf $DIR/$tfile || error "tmp file removal failed"
18188 }
18189 run_test 218 "parallel read and truncate should not deadlock"
18190
18191 test_219() {
18192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18193
18194         # write one partial page
18195         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18196         # set no grant so vvp_io_commit_write will do sync write
18197         $LCTL set_param fail_loc=0x411
18198         # write a full page at the end of file
18199         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18200
18201         $LCTL set_param fail_loc=0
18202         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18203         $LCTL set_param fail_loc=0x411
18204         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18205
18206         # LU-4201
18207         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18208         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18209 }
18210 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18211
18212 test_220() { #LU-325
18213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18214         remote_ost_nodsh && skip "remote OST with nodsh"
18215         remote_mds_nodsh && skip "remote MDS with nodsh"
18216         remote_mgs_nodsh && skip "remote MGS with nodsh"
18217
18218         local OSTIDX=0
18219
18220         # create on MDT0000 so the last_id and next_id are correct
18221         mkdir $DIR/$tdir
18222         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18223         OST=${OST%_UUID}
18224
18225         # on the mdt's osc
18226         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18227         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18228                         osp.$mdtosc_proc1.prealloc_last_id)
18229         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18230                         osp.$mdtosc_proc1.prealloc_next_id)
18231
18232         $LFS df -i
18233
18234         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18235         #define OBD_FAIL_OST_ENOINO              0x229
18236         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18237         create_pool $FSNAME.$TESTNAME || return 1
18238         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18239
18240         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18241
18242         MDSOBJS=$((last_id - next_id))
18243         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18244
18245         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18246         echo "OST still has $count kbytes free"
18247
18248         echo "create $MDSOBJS files @next_id..."
18249         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18250
18251         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18252                         osp.$mdtosc_proc1.prealloc_last_id)
18253         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18254                         osp.$mdtosc_proc1.prealloc_next_id)
18255
18256         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18257         $LFS df -i
18258
18259         echo "cleanup..."
18260
18261         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18262         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18263
18264         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18265                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18266         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18267                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18268         echo "unlink $MDSOBJS files @$next_id..."
18269         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18270 }
18271 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18272
18273 test_221() {
18274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18275
18276         dd if=`which date` of=$MOUNT/date oflag=sync
18277         chmod +x $MOUNT/date
18278
18279         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18280         $LCTL set_param fail_loc=0x80001401
18281
18282         $MOUNT/date > /dev/null
18283         rm -f $MOUNT/date
18284 }
18285 run_test 221 "make sure fault and truncate race to not cause OOM"
18286
18287 test_222a () {
18288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18289
18290         rm -rf $DIR/$tdir
18291         test_mkdir $DIR/$tdir
18292         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18293         createmany -o $DIR/$tdir/$tfile 10
18294         cancel_lru_locks mdc
18295         cancel_lru_locks osc
18296         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18297         $LCTL set_param fail_loc=0x31a
18298         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18299         $LCTL set_param fail_loc=0
18300         rm -r $DIR/$tdir
18301 }
18302 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18303
18304 test_222b () {
18305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18306
18307         rm -rf $DIR/$tdir
18308         test_mkdir $DIR/$tdir
18309         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18310         createmany -o $DIR/$tdir/$tfile 10
18311         cancel_lru_locks mdc
18312         cancel_lru_locks osc
18313         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18314         $LCTL set_param fail_loc=0x31a
18315         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18316         $LCTL set_param fail_loc=0
18317 }
18318 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18319
18320 test_223 () {
18321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18322
18323         rm -rf $DIR/$tdir
18324         test_mkdir $DIR/$tdir
18325         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18326         createmany -o $DIR/$tdir/$tfile 10
18327         cancel_lru_locks mdc
18328         cancel_lru_locks osc
18329         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18330         $LCTL set_param fail_loc=0x31b
18331         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18332         $LCTL set_param fail_loc=0
18333         rm -r $DIR/$tdir
18334 }
18335 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18336
18337 test_224a() { # LU-1039, MRP-303
18338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18339
18340         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18341         $LCTL set_param fail_loc=0x508
18342         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18343         $LCTL set_param fail_loc=0
18344         df $DIR
18345 }
18346 run_test 224a "Don't panic on bulk IO failure"
18347
18348 test_224b() { # LU-1039, MRP-303
18349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18350
18351         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18352         cancel_lru_locks osc
18353         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18354         $LCTL set_param fail_loc=0x515
18355         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18356         $LCTL set_param fail_loc=0
18357         df $DIR
18358 }
18359 run_test 224b "Don't panic on bulk IO failure"
18360
18361 test_224c() { # LU-6441
18362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18363         remote_mds_nodsh && skip "remote MDS with nodsh"
18364
18365         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18366         save_writethrough $p
18367         set_cache writethrough on
18368
18369         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18370         local at_max=$($LCTL get_param -n at_max)
18371         local timeout=$($LCTL get_param -n timeout)
18372         local test_at="at_max"
18373         local param_at="$FSNAME.sys.at_max"
18374         local test_timeout="timeout"
18375         local param_timeout="$FSNAME.sys.timeout"
18376
18377         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18378
18379         set_persistent_param_and_check client "$test_at" "$param_at" 0
18380         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18381
18382         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18383         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18384         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18385         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18386         sync
18387         do_facet ost1 "$LCTL set_param fail_loc=0"
18388
18389         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18390         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18391                 $timeout
18392
18393         $LCTL set_param -n $pages_per_rpc
18394         restore_lustre_params < $p
18395         rm -f $p
18396 }
18397 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18398
18399 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18400 test_225a () {
18401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18402         if [ -z ${MDSSURVEY} ]; then
18403                 skip_env "mds-survey not found"
18404         fi
18405         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18406                 skip "Need MDS version at least 2.2.51"
18407
18408         local mds=$(facet_host $SINGLEMDS)
18409         local target=$(do_nodes $mds 'lctl dl' |
18410                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18411
18412         local cmd1="file_count=1000 thrhi=4"
18413         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18414         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18415         local cmd="$cmd1 $cmd2 $cmd3"
18416
18417         rm -f ${TMP}/mds_survey*
18418         echo + $cmd
18419         eval $cmd || error "mds-survey with zero-stripe failed"
18420         cat ${TMP}/mds_survey*
18421         rm -f ${TMP}/mds_survey*
18422 }
18423 run_test 225a "Metadata survey sanity with zero-stripe"
18424
18425 test_225b () {
18426         if [ -z ${MDSSURVEY} ]; then
18427                 skip_env "mds-survey not found"
18428         fi
18429         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18430                 skip "Need MDS version at least 2.2.51"
18431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18432         remote_mds_nodsh && skip "remote MDS with nodsh"
18433         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18434                 skip_env "Need to mount OST to test"
18435         fi
18436
18437         local mds=$(facet_host $SINGLEMDS)
18438         local target=$(do_nodes $mds 'lctl dl' |
18439                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18440
18441         local cmd1="file_count=1000 thrhi=4"
18442         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18443         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18444         local cmd="$cmd1 $cmd2 $cmd3"
18445
18446         rm -f ${TMP}/mds_survey*
18447         echo + $cmd
18448         eval $cmd || error "mds-survey with stripe_count failed"
18449         cat ${TMP}/mds_survey*
18450         rm -f ${TMP}/mds_survey*
18451 }
18452 run_test 225b "Metadata survey sanity with stripe_count = 1"
18453
18454 mcreate_path2fid () {
18455         local mode=$1
18456         local major=$2
18457         local minor=$3
18458         local name=$4
18459         local desc=$5
18460         local path=$DIR/$tdir/$name
18461         local fid
18462         local rc
18463         local fid_path
18464
18465         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18466                 error "cannot create $desc"
18467
18468         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18469         rc=$?
18470         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18471
18472         fid_path=$($LFS fid2path $MOUNT $fid)
18473         rc=$?
18474         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18475
18476         [ "$path" == "$fid_path" ] ||
18477                 error "fid2path returned $fid_path, expected $path"
18478
18479         echo "pass with $path and $fid"
18480 }
18481
18482 test_226a () {
18483         rm -rf $DIR/$tdir
18484         mkdir -p $DIR/$tdir
18485
18486         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18487         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18488         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18489         mcreate_path2fid 0040666 0 0 dir "directory"
18490         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18491         mcreate_path2fid 0100666 0 0 file "regular file"
18492         mcreate_path2fid 0120666 0 0 link "symbolic link"
18493         mcreate_path2fid 0140666 0 0 sock "socket"
18494 }
18495 run_test 226a "call path2fid and fid2path on files of all type"
18496
18497 test_226b () {
18498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18499
18500         local MDTIDX=1
18501
18502         rm -rf $DIR/$tdir
18503         mkdir -p $DIR/$tdir
18504         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18505                 error "create remote directory failed"
18506         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18507         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18508                                 "character special file (null)"
18509         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18510                                 "character special file (no device)"
18511         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18512         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18513                                 "block special file (loop)"
18514         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18515         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18516         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18517 }
18518 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18519
18520 test_226c () {
18521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18522         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18523                 skip "Need MDS version at least 2.13.55"
18524
18525         local submnt=/mnt/submnt
18526         local srcfile=/etc/passwd
18527         local dstfile=$submnt/passwd
18528         local path
18529         local fid
18530
18531         rm -rf $DIR/$tdir
18532         rm -rf $submnt
18533         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18534                 error "create remote directory failed"
18535         mkdir -p $submnt || error "create $submnt failed"
18536         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18537                 error "mount $submnt failed"
18538         stack_trap "umount $submnt" EXIT
18539
18540         cp $srcfile $dstfile
18541         fid=$($LFS path2fid $dstfile)
18542         path=$($LFS fid2path $submnt "$fid")
18543         [ "$path" = "$dstfile" ] ||
18544                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18545 }
18546 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18547
18548 # LU-1299 Executing or running ldd on a truncated executable does not
18549 # cause an out-of-memory condition.
18550 test_227() {
18551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18552         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18553
18554         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18555         chmod +x $MOUNT/date
18556
18557         $MOUNT/date > /dev/null
18558         ldd $MOUNT/date > /dev/null
18559         rm -f $MOUNT/date
18560 }
18561 run_test 227 "running truncated executable does not cause OOM"
18562
18563 # LU-1512 try to reuse idle OI blocks
18564 test_228a() {
18565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18566         remote_mds_nodsh && skip "remote MDS with nodsh"
18567         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18568
18569         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18570         local myDIR=$DIR/$tdir
18571
18572         mkdir -p $myDIR
18573         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18574         $LCTL set_param fail_loc=0x80001002
18575         createmany -o $myDIR/t- 10000
18576         $LCTL set_param fail_loc=0
18577         # The guard is current the largest FID holder
18578         touch $myDIR/guard
18579         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18580                     tr -d '[')
18581         local IDX=$(($SEQ % 64))
18582
18583         do_facet $SINGLEMDS sync
18584         # Make sure journal flushed.
18585         sleep 6
18586         local blk1=$(do_facet $SINGLEMDS \
18587                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18588                      grep Blockcount | awk '{print $4}')
18589
18590         # Remove old files, some OI blocks will become idle.
18591         unlinkmany $myDIR/t- 10000
18592         # Create new files, idle OI blocks should be reused.
18593         createmany -o $myDIR/t- 2000
18594         do_facet $SINGLEMDS sync
18595         # Make sure journal flushed.
18596         sleep 6
18597         local blk2=$(do_facet $SINGLEMDS \
18598                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18599                      grep Blockcount | awk '{print $4}')
18600
18601         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18602 }
18603 run_test 228a "try to reuse idle OI blocks"
18604
18605 test_228b() {
18606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18607         remote_mds_nodsh && skip "remote MDS with nodsh"
18608         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18609
18610         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18611         local myDIR=$DIR/$tdir
18612
18613         mkdir -p $myDIR
18614         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18615         $LCTL set_param fail_loc=0x80001002
18616         createmany -o $myDIR/t- 10000
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- 10000
18633
18634         # stop the MDT
18635         stop $SINGLEMDS || error "Fail to stop MDT."
18636         # remount the MDT
18637         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18638
18639         df $MOUNT || error "Fail to df."
18640         # Create new files, idle OI blocks should be reused.
18641         createmany -o $myDIR/t- 2000
18642         do_facet $SINGLEMDS sync
18643         # Make sure journal flushed.
18644         sleep 6
18645         local blk2=$(do_facet $SINGLEMDS \
18646                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18647                      grep Blockcount | awk '{print $4}')
18648
18649         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18650 }
18651 run_test 228b "idle OI blocks can be reused after MDT restart"
18652
18653 #LU-1881
18654 test_228c() {
18655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18656         remote_mds_nodsh && skip "remote MDS with nodsh"
18657         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18658
18659         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18660         local myDIR=$DIR/$tdir
18661
18662         mkdir -p $myDIR
18663         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18664         $LCTL set_param fail_loc=0x80001002
18665         # 20000 files can guarantee there are index nodes in the OI file
18666         createmany -o $myDIR/t- 20000
18667         $LCTL set_param fail_loc=0
18668         # The guard is current the largest FID holder
18669         touch $myDIR/guard
18670         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18671                     tr -d '[')
18672         local IDX=$(($SEQ % 64))
18673
18674         do_facet $SINGLEMDS sync
18675         # Make sure journal flushed.
18676         sleep 6
18677         local blk1=$(do_facet $SINGLEMDS \
18678                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18679                      grep Blockcount | awk '{print $4}')
18680
18681         # Remove old files, some OI blocks will become idle.
18682         unlinkmany $myDIR/t- 20000
18683         rm -f $myDIR/guard
18684         # The OI file should become empty now
18685
18686         # Create new files, idle OI blocks should be reused.
18687         createmany -o $myDIR/t- 2000
18688         do_facet $SINGLEMDS sync
18689         # Make sure journal flushed.
18690         sleep 6
18691         local blk2=$(do_facet $SINGLEMDS \
18692                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18693                      grep Blockcount | awk '{print $4}')
18694
18695         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18696 }
18697 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18698
18699 test_229() { # LU-2482, LU-3448
18700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18701         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18702         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18703                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18704
18705         rm -f $DIR/$tfile
18706
18707         # Create a file with a released layout and stripe count 2.
18708         $MULTIOP $DIR/$tfile H2c ||
18709                 error "failed to create file with released layout"
18710
18711         $LFS getstripe -v $DIR/$tfile
18712
18713         local pattern=$($LFS getstripe -L $DIR/$tfile)
18714         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18715
18716         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18717                 error "getstripe"
18718         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18719         stat $DIR/$tfile || error "failed to stat released file"
18720
18721         chown $RUNAS_ID $DIR/$tfile ||
18722                 error "chown $RUNAS_ID $DIR/$tfile failed"
18723
18724         chgrp $RUNAS_ID $DIR/$tfile ||
18725                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18726
18727         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18728         rm $DIR/$tfile || error "failed to remove released file"
18729 }
18730 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18731
18732 test_230a() {
18733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18734         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18735         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18736                 skip "Need MDS version at least 2.11.52"
18737
18738         local MDTIDX=1
18739
18740         test_mkdir $DIR/$tdir
18741         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18742         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18743         [ $mdt_idx -ne 0 ] &&
18744                 error "create local directory on wrong MDT $mdt_idx"
18745
18746         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18747                         error "create remote directory failed"
18748         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18749         [ $mdt_idx -ne $MDTIDX ] &&
18750                 error "create remote directory on wrong MDT $mdt_idx"
18751
18752         createmany -o $DIR/$tdir/test_230/t- 10 ||
18753                 error "create files on remote directory failed"
18754         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18755         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18756         rm -r $DIR/$tdir || error "unlink remote directory failed"
18757 }
18758 run_test 230a "Create remote directory and files under the remote directory"
18759
18760 test_230b() {
18761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18763         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18764                 skip "Need MDS version at least 2.11.52"
18765
18766         local MDTIDX=1
18767         local mdt_index
18768         local i
18769         local file
18770         local pid
18771         local stripe_count
18772         local migrate_dir=$DIR/$tdir/migrate_dir
18773         local other_dir=$DIR/$tdir/other_dir
18774
18775         test_mkdir $DIR/$tdir
18776         test_mkdir -i0 -c1 $migrate_dir
18777         test_mkdir -i0 -c1 $other_dir
18778         for ((i=0; i<10; i++)); do
18779                 mkdir -p $migrate_dir/dir_${i}
18780                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18781                         error "create files under remote dir failed $i"
18782         done
18783
18784         cp /etc/passwd $migrate_dir/$tfile
18785         cp /etc/passwd $other_dir/$tfile
18786         chattr +SAD $migrate_dir
18787         chattr +SAD $migrate_dir/$tfile
18788
18789         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18790         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18791         local old_dir_mode=$(stat -c%f $migrate_dir)
18792         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18793
18794         mkdir -p $migrate_dir/dir_default_stripe2
18795         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18796         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18797
18798         mkdir -p $other_dir
18799         ln $migrate_dir/$tfile $other_dir/luna
18800         ln $migrate_dir/$tfile $migrate_dir/sofia
18801         ln $other_dir/$tfile $migrate_dir/david
18802         ln -s $migrate_dir/$tfile $other_dir/zachary
18803         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18804         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18805
18806         local len
18807         local lnktgt
18808
18809         # inline symlink
18810         for len in 58 59 60; do
18811                 lnktgt=$(str_repeat 'l' $len)
18812                 touch $migrate_dir/$lnktgt
18813                 ln -s $lnktgt $migrate_dir/${len}char_ln
18814         done
18815
18816         # PATH_MAX
18817         for len in 4094 4095; do
18818                 lnktgt=$(str_repeat 'l' $len)
18819                 ln -s $lnktgt $migrate_dir/${len}char_ln
18820         done
18821
18822         # NAME_MAX
18823         for len in 254 255; do
18824                 touch $migrate_dir/$(str_repeat 'l' $len)
18825         done
18826
18827         $LFS migrate -m $MDTIDX $migrate_dir ||
18828                 error "fails on migrating remote dir to MDT1"
18829
18830         echo "migratate to MDT1, then checking.."
18831         for ((i = 0; i < 10; i++)); do
18832                 for file in $(find $migrate_dir/dir_${i}); do
18833                         mdt_index=$($LFS getstripe -m $file)
18834                         # broken symlink getstripe will fail
18835                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18836                                 error "$file is not on MDT${MDTIDX}"
18837                 done
18838         done
18839
18840         # the multiple link file should still in MDT0
18841         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18842         [ $mdt_index == 0 ] ||
18843                 error "$file is not on MDT${MDTIDX}"
18844
18845         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18846         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18847                 error " expect $old_dir_flag get $new_dir_flag"
18848
18849         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18850         [ "$old_file_flag" = "$new_file_flag" ] ||
18851                 error " expect $old_file_flag get $new_file_flag"
18852
18853         local new_dir_mode=$(stat -c%f $migrate_dir)
18854         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18855                 error "expect mode $old_dir_mode get $new_dir_mode"
18856
18857         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18858         [ "$old_file_mode" = "$new_file_mode" ] ||
18859                 error "expect mode $old_file_mode get $new_file_mode"
18860
18861         diff /etc/passwd $migrate_dir/$tfile ||
18862                 error "$tfile different after migration"
18863
18864         diff /etc/passwd $other_dir/luna ||
18865                 error "luna different after migration"
18866
18867         diff /etc/passwd $migrate_dir/sofia ||
18868                 error "sofia different after migration"
18869
18870         diff /etc/passwd $migrate_dir/david ||
18871                 error "david different after migration"
18872
18873         diff /etc/passwd $other_dir/zachary ||
18874                 error "zachary different after migration"
18875
18876         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18877                 error "${tfile}_ln different after migration"
18878
18879         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18880                 error "${tfile}_ln_other different after migration"
18881
18882         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18883         [ $stripe_count = 2 ] ||
18884                 error "dir strpe_count $d != 2 after migration."
18885
18886         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18887         [ $stripe_count = 2 ] ||
18888                 error "file strpe_count $d != 2 after migration."
18889
18890         #migrate back to MDT0
18891         MDTIDX=0
18892
18893         $LFS migrate -m $MDTIDX $migrate_dir ||
18894                 error "fails on migrating remote dir to MDT0"
18895
18896         echo "migrate back to MDT0, checking.."
18897         for file in $(find $migrate_dir); do
18898                 mdt_index=$($LFS getstripe -m $file)
18899                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18900                         error "$file is not on MDT${MDTIDX}"
18901         done
18902
18903         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18904         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18905                 error " expect $old_dir_flag get $new_dir_flag"
18906
18907         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18908         [ "$old_file_flag" = "$new_file_flag" ] ||
18909                 error " expect $old_file_flag get $new_file_flag"
18910
18911         local new_dir_mode=$(stat -c%f $migrate_dir)
18912         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18913                 error "expect mode $old_dir_mode get $new_dir_mode"
18914
18915         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18916         [ "$old_file_mode" = "$new_file_mode" ] ||
18917                 error "expect mode $old_file_mode get $new_file_mode"
18918
18919         diff /etc/passwd ${migrate_dir}/$tfile ||
18920                 error "$tfile different after migration"
18921
18922         diff /etc/passwd ${other_dir}/luna ||
18923                 error "luna different after migration"
18924
18925         diff /etc/passwd ${migrate_dir}/sofia ||
18926                 error "sofia different after migration"
18927
18928         diff /etc/passwd ${other_dir}/zachary ||
18929                 error "zachary different after migration"
18930
18931         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18932                 error "${tfile}_ln different after migration"
18933
18934         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18935                 error "${tfile}_ln_other different after migration"
18936
18937         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18938         [ $stripe_count = 2 ] ||
18939                 error "dir strpe_count $d != 2 after migration."
18940
18941         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18942         [ $stripe_count = 2 ] ||
18943                 error "file strpe_count $d != 2 after migration."
18944
18945         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18946 }
18947 run_test 230b "migrate directory"
18948
18949 test_230c() {
18950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18952         remote_mds_nodsh && skip "remote MDS with nodsh"
18953         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18954                 skip "Need MDS version at least 2.11.52"
18955
18956         local MDTIDX=1
18957         local total=3
18958         local mdt_index
18959         local file
18960         local migrate_dir=$DIR/$tdir/migrate_dir
18961
18962         #If migrating directory fails in the middle, all entries of
18963         #the directory is still accessiable.
18964         test_mkdir $DIR/$tdir
18965         test_mkdir -i0 -c1 $migrate_dir
18966         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18967         stat $migrate_dir
18968         createmany -o $migrate_dir/f $total ||
18969                 error "create files under ${migrate_dir} failed"
18970
18971         # fail after migrating top dir, and this will fail only once, so the
18972         # first sub file migration will fail (currently f3), others succeed.
18973         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18974         do_facet mds1 lctl set_param fail_loc=0x1801
18975         local t=$(ls $migrate_dir | wc -l)
18976         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18977                 error "migrate should fail"
18978         local u=$(ls $migrate_dir | wc -l)
18979         [ "$u" == "$t" ] || error "$u != $t during migration"
18980
18981         # add new dir/file should succeed
18982         mkdir $migrate_dir/dir ||
18983                 error "mkdir failed under migrating directory"
18984         touch $migrate_dir/file ||
18985                 error "create file failed under migrating directory"
18986
18987         # add file with existing name should fail
18988         for file in $migrate_dir/f*; do
18989                 stat $file > /dev/null || error "stat $file failed"
18990                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18991                         error "open(O_CREAT|O_EXCL) $file should fail"
18992                 $MULTIOP $file m && error "create $file should fail"
18993                 touch $DIR/$tdir/remote_dir/$tfile ||
18994                         error "touch $tfile failed"
18995                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18996                         error "link $file should fail"
18997                 mdt_index=$($LFS getstripe -m $file)
18998                 if [ $mdt_index == 0 ]; then
18999                         # file failed to migrate is not allowed to rename to
19000                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19001                                 error "rename to $file should fail"
19002                 else
19003                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19004                                 error "rename to $file failed"
19005                 fi
19006                 echo hello >> $file || error "write $file failed"
19007         done
19008
19009         # resume migration with different options should fail
19010         $LFS migrate -m 0 $migrate_dir &&
19011                 error "migrate -m 0 $migrate_dir should fail"
19012
19013         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19014                 error "migrate -c 2 $migrate_dir should fail"
19015
19016         # resume migration should succeed
19017         $LFS migrate -m $MDTIDX $migrate_dir ||
19018                 error "migrate $migrate_dir failed"
19019
19020         echo "Finish migration, then checking.."
19021         for file in $(find $migrate_dir); do
19022                 mdt_index=$($LFS getstripe -m $file)
19023                 [ $mdt_index == $MDTIDX ] ||
19024                         error "$file is not on MDT${MDTIDX}"
19025         done
19026
19027         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19028 }
19029 run_test 230c "check directory accessiblity if migration failed"
19030
19031 test_230d() {
19032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19034         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19035                 skip "Need MDS version at least 2.11.52"
19036         # LU-11235
19037         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19038
19039         local migrate_dir=$DIR/$tdir/migrate_dir
19040         local old_index
19041         local new_index
19042         local old_count
19043         local new_count
19044         local new_hash
19045         local mdt_index
19046         local i
19047         local j
19048
19049         old_index=$((RANDOM % MDSCOUNT))
19050         old_count=$((MDSCOUNT - old_index))
19051         new_index=$((RANDOM % MDSCOUNT))
19052         new_count=$((MDSCOUNT - new_index))
19053         new_hash=1 # for all_char
19054
19055         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19056         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19057
19058         test_mkdir $DIR/$tdir
19059         test_mkdir -i $old_index -c $old_count $migrate_dir
19060
19061         for ((i=0; i<100; i++)); do
19062                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19063                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19064                         error "create files under remote dir failed $i"
19065         done
19066
19067         echo -n "Migrate from MDT$old_index "
19068         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19069         echo -n "to MDT$new_index"
19070         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19071         echo
19072
19073         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19074         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19075                 error "migrate remote dir error"
19076
19077         echo "Finish migration, then checking.."
19078         for file in $(find $migrate_dir); do
19079                 mdt_index=$($LFS getstripe -m $file)
19080                 if [ $mdt_index -lt $new_index ] ||
19081                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19082                         error "$file is on MDT$mdt_index"
19083                 fi
19084         done
19085
19086         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19087 }
19088 run_test 230d "check migrate big directory"
19089
19090 test_230e() {
19091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19093         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19094                 skip "Need MDS version at least 2.11.52"
19095
19096         local i
19097         local j
19098         local a_fid
19099         local b_fid
19100
19101         mkdir -p $DIR/$tdir
19102         mkdir $DIR/$tdir/migrate_dir
19103         mkdir $DIR/$tdir/other_dir
19104         touch $DIR/$tdir/migrate_dir/a
19105         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19106         ls $DIR/$tdir/other_dir
19107
19108         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19109                 error "migrate dir fails"
19110
19111         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19112         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19113
19114         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19115         [ $mdt_index == 0 ] || error "a is not on MDT0"
19116
19117         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19118                 error "migrate dir fails"
19119
19120         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19121         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19122
19123         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19124         [ $mdt_index == 1 ] || error "a is not on MDT1"
19125
19126         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19127         [ $mdt_index == 1 ] || error "b is not on MDT1"
19128
19129         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19130         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19131
19132         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19133
19134         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19135 }
19136 run_test 230e "migrate mulitple local link files"
19137
19138 test_230f() {
19139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19140         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19141         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19142                 skip "Need MDS version at least 2.11.52"
19143
19144         local a_fid
19145         local ln_fid
19146
19147         mkdir -p $DIR/$tdir
19148         mkdir $DIR/$tdir/migrate_dir
19149         $LFS mkdir -i1 $DIR/$tdir/other_dir
19150         touch $DIR/$tdir/migrate_dir/a
19151         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19152         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19153         ls $DIR/$tdir/other_dir
19154
19155         # a should be migrated to MDT1, since no other links on MDT0
19156         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19157                 error "#1 migrate dir fails"
19158         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19159         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19160         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19161         [ $mdt_index == 1 ] || error "a is not on MDT1"
19162
19163         # a should stay on MDT1, because it is a mulitple link file
19164         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19165                 error "#2 migrate dir fails"
19166         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19167         [ $mdt_index == 1 ] || error "a is not on MDT1"
19168
19169         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19170                 error "#3 migrate dir fails"
19171
19172         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19173         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19174         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19175
19176         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19177         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19178
19179         # a should be migrated to MDT0, since no other links on MDT1
19180         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19181                 error "#4 migrate dir fails"
19182         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19183         [ $mdt_index == 0 ] || error "a is not on MDT0"
19184
19185         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19186 }
19187 run_test 230f "migrate mulitple remote link files"
19188
19189 test_230g() {
19190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19192         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19193                 skip "Need MDS version at least 2.11.52"
19194
19195         mkdir -p $DIR/$tdir/migrate_dir
19196
19197         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19198                 error "migrating dir to non-exist MDT succeeds"
19199         true
19200 }
19201 run_test 230g "migrate dir to non-exist MDT"
19202
19203 test_230h() {
19204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19206         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19207                 skip "Need MDS version at least 2.11.52"
19208
19209         local mdt_index
19210
19211         mkdir -p $DIR/$tdir/migrate_dir
19212
19213         $LFS migrate -m1 $DIR &&
19214                 error "migrating mountpoint1 should fail"
19215
19216         $LFS migrate -m1 $DIR/$tdir/.. &&
19217                 error "migrating mountpoint2 should fail"
19218
19219         # same as mv
19220         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19221                 error "migrating $tdir/migrate_dir/.. should fail"
19222
19223         true
19224 }
19225 run_test 230h "migrate .. and root"
19226
19227 test_230i() {
19228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19230         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19231                 skip "Need MDS version at least 2.11.52"
19232
19233         mkdir -p $DIR/$tdir/migrate_dir
19234
19235         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19236                 error "migration fails with a tailing slash"
19237
19238         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19239                 error "migration fails with two tailing slashes"
19240 }
19241 run_test 230i "lfs migrate -m tolerates trailing slashes"
19242
19243 test_230j() {
19244         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19245         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19246                 skip "Need MDS version at least 2.11.52"
19247
19248         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19249         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19250                 error "create $tfile failed"
19251         cat /etc/passwd > $DIR/$tdir/$tfile
19252
19253         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19254
19255         cmp /etc/passwd $DIR/$tdir/$tfile ||
19256                 error "DoM file mismatch after migration"
19257 }
19258 run_test 230j "DoM file data not changed after dir migration"
19259
19260 test_230k() {
19261         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19262         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19263                 skip "Need MDS version at least 2.11.56"
19264
19265         local total=20
19266         local files_on_starting_mdt=0
19267
19268         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19269         $LFS getdirstripe $DIR/$tdir
19270         for i in $(seq $total); do
19271                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19272                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19273                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19274         done
19275
19276         echo "$files_on_starting_mdt files on MDT0"
19277
19278         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19279         $LFS getdirstripe $DIR/$tdir
19280
19281         files_on_starting_mdt=0
19282         for i in $(seq $total); do
19283                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19284                         error "file $tfile.$i mismatch after migration"
19285                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19286                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19287         done
19288
19289         echo "$files_on_starting_mdt files on MDT1 after migration"
19290         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19291
19292         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19293         $LFS getdirstripe $DIR/$tdir
19294
19295         files_on_starting_mdt=0
19296         for i in $(seq $total); do
19297                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19298                         error "file $tfile.$i mismatch after 2nd migration"
19299                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19300                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19301         done
19302
19303         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19304         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19305
19306         true
19307 }
19308 run_test 230k "file data not changed after dir migration"
19309
19310 test_230l() {
19311         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19312         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19313                 skip "Need MDS version at least 2.11.56"
19314
19315         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19316         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19317                 error "create files under remote dir failed $i"
19318         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19319 }
19320 run_test 230l "readdir between MDTs won't crash"
19321
19322 test_230m() {
19323         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19324         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19325                 skip "Need MDS version at least 2.11.56"
19326
19327         local MDTIDX=1
19328         local mig_dir=$DIR/$tdir/migrate_dir
19329         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19330         local shortstr="b"
19331         local val
19332
19333         echo "Creating files and dirs with xattrs"
19334         test_mkdir $DIR/$tdir
19335         test_mkdir -i0 -c1 $mig_dir
19336         mkdir $mig_dir/dir
19337         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19338                 error "cannot set xattr attr1 on dir"
19339         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19340                 error "cannot set xattr attr2 on dir"
19341         touch $mig_dir/dir/f0
19342         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19343                 error "cannot set xattr attr1 on file"
19344         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19345                 error "cannot set xattr attr2 on file"
19346         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19347         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19348         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19349         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19350         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19351         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19352         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19353         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19354         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19355
19356         echo "Migrating to MDT1"
19357         $LFS migrate -m $MDTIDX $mig_dir ||
19358                 error "fails on migrating dir to MDT1"
19359
19360         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19361         echo "Checking xattrs"
19362         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19363         [ "$val" = $longstr ] ||
19364                 error "expecting xattr1 $longstr on dir, found $val"
19365         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19366         [ "$val" = $shortstr ] ||
19367                 error "expecting xattr2 $shortstr on dir, found $val"
19368         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19369         [ "$val" = $longstr ] ||
19370                 error "expecting xattr1 $longstr on file, found $val"
19371         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19372         [ "$val" = $shortstr ] ||
19373                 error "expecting xattr2 $shortstr on file, found $val"
19374 }
19375 run_test 230m "xattrs not changed after dir migration"
19376
19377 test_230n() {
19378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19379         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19380                 skip "Need MDS version at least 2.13.53"
19381
19382         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19383         cat /etc/hosts > $DIR/$tdir/$tfile
19384         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19385         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19386
19387         cmp /etc/hosts $DIR/$tdir/$tfile ||
19388                 error "File data mismatch after migration"
19389 }
19390 run_test 230n "Dir migration with mirrored file"
19391
19392 test_230o() {
19393         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19394         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19395                 skip "Need MDS version at least 2.13.52"
19396
19397         local mdts=$(comma_list $(mdts_nodes))
19398         local timeout=100
19399         local restripe_status
19400         local delta
19401         local i
19402
19403         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19404
19405         # in case "crush" hash type is not set
19406         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19407
19408         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19409                            mdt.*MDT0000.enable_dir_restripe)
19410         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19411         stack_trap "do_nodes $mdts $LCTL set_param \
19412                     mdt.*.enable_dir_restripe=$restripe_status"
19413
19414         mkdir $DIR/$tdir
19415         createmany -m $DIR/$tdir/f 100 ||
19416                 error "create files under remote dir failed $i"
19417         createmany -d $DIR/$tdir/d 100 ||
19418                 error "create dirs under remote dir failed $i"
19419
19420         for i in $(seq 2 $MDSCOUNT); do
19421                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19422                 $LFS setdirstripe -c $i $DIR/$tdir ||
19423                         error "split -c $i $tdir failed"
19424                 wait_update $HOSTNAME \
19425                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19426                         error "dir split not finished"
19427                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19428                         awk '/migrate/ {sum += $2} END { print sum }')
19429                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19430                 # delta is around total_files/stripe_count
19431                 (( $delta < 200 / (i - 1) + 4 )) ||
19432                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19433         done
19434 }
19435 run_test 230o "dir split"
19436
19437 test_230p() {
19438         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19439         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19440                 skip "Need MDS version at least 2.13.52"
19441
19442         local mdts=$(comma_list $(mdts_nodes))
19443         local timeout=100
19444         local restripe_status
19445         local delta
19446         local i
19447
19448         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19449
19450         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19451
19452         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19453                            mdt.*MDT0000.enable_dir_restripe)
19454         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19455         stack_trap "do_nodes $mdts $LCTL set_param \
19456                     mdt.*.enable_dir_restripe=$restripe_status"
19457
19458         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19459         createmany -m $DIR/$tdir/f 100 ||
19460                 error "create files under remote dir failed $i"
19461         createmany -d $DIR/$tdir/d 100 ||
19462                 error "create dirs under remote dir failed $i"
19463
19464         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19465                 local mdt_hash="crush"
19466
19467                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19468                 $LFS setdirstripe -c $i $DIR/$tdir ||
19469                         error "split -c $i $tdir failed"
19470                 [ $i -eq 1 ] && mdt_hash="none"
19471                 wait_update $HOSTNAME \
19472                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19473                         error "dir merge not finished"
19474                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19475                         awk '/migrate/ {sum += $2} END { print sum }')
19476                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19477                 # delta is around total_files/stripe_count
19478                 (( $delta < 200 / i + 4 )) ||
19479                         error "$delta files migrated >= $((200 / i + 4))"
19480         done
19481 }
19482 run_test 230p "dir merge"
19483
19484 test_230q() {
19485         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19486         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19487                 skip "Need MDS version at least 2.13.52"
19488
19489         local mdts=$(comma_list $(mdts_nodes))
19490         local saved_threshold=$(do_facet mds1 \
19491                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19492         local saved_delta=$(do_facet mds1 \
19493                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19494         local threshold=100
19495         local delta=2
19496         local total=0
19497         local stripe_count=0
19498         local stripe_index
19499         local nr_files
19500         local create
19501
19502         # test with fewer files on ZFS
19503         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19504
19505         stack_trap "do_nodes $mdts $LCTL set_param \
19506                     mdt.*.dir_split_count=$saved_threshold"
19507         stack_trap "do_nodes $mdts $LCTL set_param \
19508                     mdt.*.dir_split_delta=$saved_delta"
19509         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19510         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19511         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19512         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19513         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19514         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19515
19516         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19517         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19518
19519         create=$((threshold * 3 / 2))
19520         while [ $stripe_count -lt $MDSCOUNT ]; do
19521                 createmany -m $DIR/$tdir/f $total $create ||
19522                         error "create sub files failed"
19523                 stat $DIR/$tdir > /dev/null
19524                 total=$((total + create))
19525                 stripe_count=$((stripe_count + delta))
19526                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19527
19528                 wait_update $HOSTNAME \
19529                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19530                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19531
19532                 wait_update $HOSTNAME \
19533                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19534                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19535
19536                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19537                 echo "$nr_files/$total files on MDT$stripe_index after split"
19538                 # allow 10% margin of imbalance with crush hash
19539                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19540                         error "$nr_files files on MDT$stripe_index after split"
19541
19542                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19543                 [ $nr_files -eq $total ] ||
19544                         error "total sub files $nr_files != $total"
19545         done
19546 }
19547 run_test 230q "dir auto split"
19548
19549 test_230r() {
19550         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19551         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19552         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19553                 skip "Need MDS version at least 2.13.54"
19554
19555         # maximum amount of local locks:
19556         # parent striped dir - 2 locks
19557         # new stripe in parent to migrate to - 1 lock
19558         # source and target - 2 locks
19559         # Total 5 locks for regular file
19560         mkdir -p $DIR/$tdir
19561         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19562         touch $DIR/$tdir/dir1/eee
19563
19564         # create 4 hardlink for 4 more locks
19565         # Total: 9 locks > RS_MAX_LOCKS (8)
19566         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19567         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19568         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19569         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19570         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19571         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19572         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19573         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19574
19575         cancel_lru_locks mdc
19576
19577         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19578                 error "migrate dir fails"
19579
19580         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19581 }
19582 run_test 230r "migrate with too many local locks"
19583
19584 test_230s() {
19585         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19586                 skip "Need MDS version at least 2.13.57"
19587
19588         local mdts=$(comma_list $(mdts_nodes))
19589         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19590                                 mdt.*MDT0000.enable_dir_restripe)
19591
19592         stack_trap "do_nodes $mdts $LCTL set_param \
19593                     mdt.*.enable_dir_restripe=$restripe_status"
19594
19595         local st
19596         for st in 0 1; do
19597                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19598                 test_mkdir $DIR/$tdir
19599                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19600                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19601                 rmdir $DIR/$tdir
19602         done
19603 }
19604 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19605
19606 test_230t()
19607 {
19608         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19609         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19610                 skip "Need MDS version at least 2.14.50"
19611
19612         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19613         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19614         $LFS project -p 1 -s $DIR/$tdir ||
19615                 error "set $tdir project id failed"
19616         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19617                 error "set subdir project id failed"
19618         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19619 }
19620 run_test 230t "migrate directory with project ID set"
19621
19622 test_231a()
19623 {
19624         # For simplicity this test assumes that max_pages_per_rpc
19625         # is the same across all OSCs
19626         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19627         local bulk_size=$((max_pages * PAGE_SIZE))
19628         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19629                                        head -n 1)
19630
19631         mkdir -p $DIR/$tdir
19632         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19633                 error "failed to set stripe with -S ${brw_size}M option"
19634
19635         # clear the OSC stats
19636         $LCTL set_param osc.*.stats=0 &>/dev/null
19637         stop_writeback
19638
19639         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19641                 oflag=direct &>/dev/null || error "dd failed"
19642
19643         sync; sleep 1; sync # just to be safe
19644         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19645         if [ x$nrpcs != "x1" ]; then
19646                 $LCTL get_param osc.*.stats
19647                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19648         fi
19649
19650         start_writeback
19651         # Drop the OSC cache, otherwise we will read from it
19652         cancel_lru_locks osc
19653
19654         # clear the OSC stats
19655         $LCTL set_param osc.*.stats=0 &>/dev/null
19656
19657         # Client reads $bulk_size.
19658         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19659                 iflag=direct &>/dev/null || error "dd failed"
19660
19661         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19662         if [ x$nrpcs != "x1" ]; then
19663                 $LCTL get_param osc.*.stats
19664                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19665         fi
19666 }
19667 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19668
19669 test_231b() {
19670         mkdir -p $DIR/$tdir
19671         local i
19672         for i in {0..1023}; do
19673                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19674                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19675                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19676         done
19677         sync
19678 }
19679 run_test 231b "must not assert on fully utilized OST request buffer"
19680
19681 test_232a() {
19682         mkdir -p $DIR/$tdir
19683         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19684
19685         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19686         do_facet ost1 $LCTL set_param fail_loc=0x31c
19687
19688         # ignore dd failure
19689         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19690
19691         do_facet ost1 $LCTL set_param fail_loc=0
19692         umount_client $MOUNT || error "umount failed"
19693         mount_client $MOUNT || error "mount failed"
19694         stop ost1 || error "cannot stop ost1"
19695         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19696 }
19697 run_test 232a "failed lock should not block umount"
19698
19699 test_232b() {
19700         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19701                 skip "Need MDS version at least 2.10.58"
19702
19703         mkdir -p $DIR/$tdir
19704         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19705         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19706         sync
19707         cancel_lru_locks osc
19708
19709         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19710         do_facet ost1 $LCTL set_param fail_loc=0x31c
19711
19712         # ignore failure
19713         $LFS data_version $DIR/$tdir/$tfile || true
19714
19715         do_facet ost1 $LCTL set_param fail_loc=0
19716         umount_client $MOUNT || error "umount failed"
19717         mount_client $MOUNT || error "mount failed"
19718         stop ost1 || error "cannot stop ost1"
19719         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19720 }
19721 run_test 232b "failed data version lock should not block umount"
19722
19723 test_233a() {
19724         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19725                 skip "Need MDS version at least 2.3.64"
19726         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19727
19728         local fid=$($LFS path2fid $MOUNT)
19729
19730         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19731                 error "cannot access $MOUNT using its FID '$fid'"
19732 }
19733 run_test 233a "checking that OBF of the FS root succeeds"
19734
19735 test_233b() {
19736         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19737                 skip "Need MDS version at least 2.5.90"
19738         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19739
19740         local fid=$($LFS path2fid $MOUNT/.lustre)
19741
19742         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19743                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19744
19745         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19746         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19747                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19748 }
19749 run_test 233b "checking that OBF of the FS .lustre succeeds"
19750
19751 test_234() {
19752         local p="$TMP/sanityN-$TESTNAME.parameters"
19753         save_lustre_params client "llite.*.xattr_cache" > $p
19754         lctl set_param llite.*.xattr_cache 1 ||
19755                 skip_env "xattr cache is not supported"
19756
19757         mkdir -p $DIR/$tdir || error "mkdir failed"
19758         touch $DIR/$tdir/$tfile || error "touch failed"
19759         # OBD_FAIL_LLITE_XATTR_ENOMEM
19760         $LCTL set_param fail_loc=0x1405
19761         getfattr -n user.attr $DIR/$tdir/$tfile &&
19762                 error "getfattr should have failed with ENOMEM"
19763         $LCTL set_param fail_loc=0x0
19764         rm -rf $DIR/$tdir
19765
19766         restore_lustre_params < $p
19767         rm -f $p
19768 }
19769 run_test 234 "xattr cache should not crash on ENOMEM"
19770
19771 test_235() {
19772         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19773                 skip "Need MDS version at least 2.4.52"
19774
19775         flock_deadlock $DIR/$tfile
19776         local RC=$?
19777         case $RC in
19778                 0)
19779                 ;;
19780                 124) error "process hangs on a deadlock"
19781                 ;;
19782                 *) error "error executing flock_deadlock $DIR/$tfile"
19783                 ;;
19784         esac
19785 }
19786 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19787
19788 #LU-2935
19789 test_236() {
19790         check_swap_layouts_support
19791
19792         local ref1=/etc/passwd
19793         local ref2=/etc/group
19794         local file1=$DIR/$tdir/f1
19795         local file2=$DIR/$tdir/f2
19796
19797         test_mkdir -c1 $DIR/$tdir
19798         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19799         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19800         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19801         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19802         local fd=$(free_fd)
19803         local cmd="exec $fd<>$file2"
19804         eval $cmd
19805         rm $file2
19806         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19807                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19808         cmd="exec $fd>&-"
19809         eval $cmd
19810         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19811
19812         #cleanup
19813         rm -rf $DIR/$tdir
19814 }
19815 run_test 236 "Layout swap on open unlinked file"
19816
19817 # LU-4659 linkea consistency
19818 test_238() {
19819         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19820                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19821                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19822                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19823
19824         touch $DIR/$tfile
19825         ln $DIR/$tfile $DIR/$tfile.lnk
19826         touch $DIR/$tfile.new
19827         mv $DIR/$tfile.new $DIR/$tfile
19828         local fid1=$($LFS path2fid $DIR/$tfile)
19829         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19830         local path1=$($LFS fid2path $FSNAME "$fid1")
19831         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19832         local path2=$($LFS fid2path $FSNAME "$fid2")
19833         [ $tfile.lnk == $path2 ] ||
19834                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19835         rm -f $DIR/$tfile*
19836 }
19837 run_test 238 "Verify linkea consistency"
19838
19839 test_239A() { # was test_239
19840         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19841                 skip "Need MDS version at least 2.5.60"
19842
19843         local list=$(comma_list $(mdts_nodes))
19844
19845         mkdir -p $DIR/$tdir
19846         createmany -o $DIR/$tdir/f- 5000
19847         unlinkmany $DIR/$tdir/f- 5000
19848         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19849                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19850         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19851                         osp.*MDT*.sync_in_flight" | calc_sum)
19852         [ "$changes" -eq 0 ] || error "$changes not synced"
19853 }
19854 run_test 239A "osp_sync test"
19855
19856 test_239a() { #LU-5297
19857         remote_mds_nodsh && skip "remote MDS with nodsh"
19858
19859         touch $DIR/$tfile
19860         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19861         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19862         chgrp $RUNAS_GID $DIR/$tfile
19863         wait_delete_completed
19864 }
19865 run_test 239a "process invalid osp sync record correctly"
19866
19867 test_239b() { #LU-5297
19868         remote_mds_nodsh && skip "remote MDS with nodsh"
19869
19870         touch $DIR/$tfile1
19871         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19872         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19873         chgrp $RUNAS_GID $DIR/$tfile1
19874         wait_delete_completed
19875         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19876         touch $DIR/$tfile2
19877         chgrp $RUNAS_GID $DIR/$tfile2
19878         wait_delete_completed
19879 }
19880 run_test 239b "process osp sync record with ENOMEM error correctly"
19881
19882 test_240() {
19883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19884         remote_mds_nodsh && skip "remote MDS with nodsh"
19885
19886         mkdir -p $DIR/$tdir
19887
19888         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19889                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19890         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19891                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19892
19893         umount_client $MOUNT || error "umount failed"
19894         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19895         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19896         mount_client $MOUNT || error "failed to mount client"
19897
19898         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19899         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19900 }
19901 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19902
19903 test_241_bio() {
19904         local count=$1
19905         local bsize=$2
19906
19907         for LOOP in $(seq $count); do
19908                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19909                 cancel_lru_locks $OSC || true
19910         done
19911 }
19912
19913 test_241_dio() {
19914         local count=$1
19915         local bsize=$2
19916
19917         for LOOP in $(seq $1); do
19918                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19919                         2>/dev/null
19920         done
19921 }
19922
19923 test_241a() { # was test_241
19924         local bsize=$PAGE_SIZE
19925
19926         (( bsize < 40960 )) && bsize=40960
19927         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19928         ls -la $DIR/$tfile
19929         cancel_lru_locks $OSC
19930         test_241_bio 1000 $bsize &
19931         PID=$!
19932         test_241_dio 1000 $bsize
19933         wait $PID
19934 }
19935 run_test 241a "bio vs dio"
19936
19937 test_241b() {
19938         local bsize=$PAGE_SIZE
19939
19940         (( bsize < 40960 )) && bsize=40960
19941         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19942         ls -la $DIR/$tfile
19943         test_241_dio 1000 $bsize &
19944         PID=$!
19945         test_241_dio 1000 $bsize
19946         wait $PID
19947 }
19948 run_test 241b "dio vs dio"
19949
19950 test_242() {
19951         remote_mds_nodsh && skip "remote MDS with nodsh"
19952
19953         mkdir -p $DIR/$tdir
19954         touch $DIR/$tdir/$tfile
19955
19956         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19957         do_facet mds1 lctl set_param fail_loc=0x105
19958         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19959
19960         do_facet mds1 lctl set_param fail_loc=0
19961         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19962 }
19963 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19964
19965 test_243()
19966 {
19967         test_mkdir $DIR/$tdir
19968         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19969 }
19970 run_test 243 "various group lock tests"
19971
19972 test_244a()
19973 {
19974         test_mkdir $DIR/$tdir
19975         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19976         sendfile_grouplock $DIR/$tdir/$tfile || \
19977                 error "sendfile+grouplock failed"
19978         rm -rf $DIR/$tdir
19979 }
19980 run_test 244a "sendfile with group lock tests"
19981
19982 test_244b()
19983 {
19984         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19985
19986         local threads=50
19987         local size=$((1024*1024))
19988
19989         test_mkdir $DIR/$tdir
19990         for i in $(seq 1 $threads); do
19991                 local file=$DIR/$tdir/file_$((i / 10))
19992                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19993                 local pids[$i]=$!
19994         done
19995         for i in $(seq 1 $threads); do
19996                 wait ${pids[$i]}
19997         done
19998 }
19999 run_test 244b "multi-threaded write with group lock"
20000
20001 test_245() {
20002         local flagname="multi_mod_rpcs"
20003         local connect_data_name="max_mod_rpcs"
20004         local out
20005
20006         # check if multiple modify RPCs flag is set
20007         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20008                 grep "connect_flags:")
20009         echo "$out"
20010
20011         echo "$out" | grep -qw $flagname
20012         if [ $? -ne 0 ]; then
20013                 echo "connect flag $flagname is not set"
20014                 return
20015         fi
20016
20017         # check if multiple modify RPCs data is set
20018         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20019         echo "$out"
20020
20021         echo "$out" | grep -qw $connect_data_name ||
20022                 error "import should have connect data $connect_data_name"
20023 }
20024 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20025
20026 cleanup_247() {
20027         local submount=$1
20028
20029         trap 0
20030         umount_client $submount
20031         rmdir $submount
20032 }
20033
20034 test_247a() {
20035         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20036                 grep -q subtree ||
20037                 skip_env "Fileset feature is not supported"
20038
20039         local submount=${MOUNT}_$tdir
20040
20041         mkdir $MOUNT/$tdir
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         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20047         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20048                 error "read $MOUNT/$tdir/$tfile failed"
20049         cleanup_247 $submount
20050 }
20051 run_test 247a "mount subdir as fileset"
20052
20053 test_247b() {
20054         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20055                 skip_env "Fileset feature is not supported"
20056
20057         local submount=${MOUNT}_$tdir
20058
20059         rm -rf $MOUNT/$tdir
20060         mkdir -p $submount || error "mkdir $submount failed"
20061         SKIP_FILESET=1
20062         FILESET="$FILESET/$tdir" mount_client $submount &&
20063                 error "mount $submount should fail"
20064         rmdir $submount
20065 }
20066 run_test 247b "mount subdir that dose not exist"
20067
20068 test_247c() {
20069         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20070                 skip_env "Fileset feature is not supported"
20071
20072         local submount=${MOUNT}_$tdir
20073
20074         mkdir -p $MOUNT/$tdir/dir1
20075         mkdir -p $submount || error "mkdir $submount failed"
20076         trap "cleanup_247 $submount" EXIT
20077         FILESET="$FILESET/$tdir" mount_client $submount ||
20078                 error "mount $submount failed"
20079         local fid=$($LFS path2fid $MOUNT/)
20080         $LFS fid2path $submount $fid && error "fid2path should fail"
20081         cleanup_247 $submount
20082 }
20083 run_test 247c "running fid2path outside subdirectory root"
20084
20085 test_247d() {
20086         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20087                 skip "Fileset feature is not supported"
20088
20089         local submount=${MOUNT}_$tdir
20090
20091         mkdir -p $MOUNT/$tdir/dir1
20092         mkdir -p $submount || error "mkdir $submount failed"
20093         FILESET="$FILESET/$tdir" mount_client $submount ||
20094                 error "mount $submount failed"
20095         trap "cleanup_247 $submount" EXIT
20096
20097         local td=$submount/dir1
20098         local fid=$($LFS path2fid $td)
20099         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20100
20101         # check that we get the same pathname back
20102         local rootpath
20103         local found
20104         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20105                 echo "$rootpath $fid"
20106                 found=$($LFS fid2path $rootpath "$fid")
20107                 [ -n "found" ] || error "fid2path should succeed"
20108                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20109         done
20110         # check wrong root path format
20111         rootpath=$submount"_wrong"
20112         found=$($LFS fid2path $rootpath "$fid")
20113         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20114
20115         cleanup_247 $submount
20116 }
20117 run_test 247d "running fid2path inside subdirectory root"
20118
20119 # LU-8037
20120 test_247e() {
20121         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20122                 grep -q subtree ||
20123                 skip "Fileset feature is not supported"
20124
20125         local submount=${MOUNT}_$tdir
20126
20127         mkdir $MOUNT/$tdir
20128         mkdir -p $submount || error "mkdir $submount failed"
20129         FILESET="$FILESET/.." mount_client $submount &&
20130                 error "mount $submount should fail"
20131         rmdir $submount
20132 }
20133 run_test 247e "mount .. as fileset"
20134
20135 test_247f() {
20136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20137         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20138                 skip "Need at least version 2.13.52"
20139         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20140                 skip "Need at least version 2.14.50"
20141         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20142                 grep -q subtree ||
20143                 skip "Fileset feature is not supported"
20144
20145         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20146         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20147                 error "mkdir remote failed"
20148         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20149         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20150                 error "mkdir striped failed"
20151         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20152
20153         local submount=${MOUNT}_$tdir
20154
20155         mkdir -p $submount || error "mkdir $submount failed"
20156         stack_trap "rmdir $submount"
20157
20158         local dir
20159         local stat
20160         local fileset=$FILESET
20161         local mdts=$(comma_list $(mdts_nodes))
20162
20163         stat=$(do_facet mds1 $LCTL get_param -n \
20164                 mdt.*MDT0000.enable_remote_subdir_mount)
20165         stack_trap "do_nodes $mdts $LCTL set_param \
20166                 mdt.*.enable_remote_subdir_mount=$stat"
20167
20168         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20169         stack_trap "umount_client $submount"
20170         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20171                 error "mount remote dir $dir should fail"
20172
20173         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20174                 $tdir/striped/. ; do
20175                 FILESET="$fileset/$dir" mount_client $submount ||
20176                         error "mount $dir failed"
20177                 umount_client $submount
20178         done
20179
20180         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20181         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20182                 error "mount $tdir/remote failed"
20183 }
20184 run_test 247f "mount striped or remote directory as fileset"
20185
20186 test_247g() {
20187         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20188         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20189                 skip "Need at least version 2.14.50"
20190
20191         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20192                 error "mkdir $tdir failed"
20193         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20194
20195         local submount=${MOUNT}_$tdir
20196
20197         mkdir -p $submount || error "mkdir $submount failed"
20198         stack_trap "rmdir $submount"
20199
20200         FILESET="$fileset/$tdir" mount_client $submount ||
20201                 error "mount $dir failed"
20202         stack_trap "umount $submount"
20203
20204         local mdts=$(comma_list $(mdts_nodes))
20205
20206         local nrpcs
20207
20208         stat $submount > /dev/null
20209         cancel_lru_locks $MDC
20210         stat $submount > /dev/null
20211         stat $submount/$tfile > /dev/null
20212         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20213         stat $submount/$tfile > /dev/null
20214         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20215                 awk '/getattr/ {sum += $2} END {print sum}')
20216
20217         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20218 }
20219 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20220
20221 test_248a() {
20222         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20223         [ -z "$fast_read_sav" ] && skip "no fast read support"
20224
20225         # create a large file for fast read verification
20226         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20227
20228         # make sure the file is created correctly
20229         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20230                 { rm -f $DIR/$tfile; skip "file creation error"; }
20231
20232         echo "Test 1: verify that fast read is 4 times faster on cache read"
20233
20234         # small read with fast read enabled
20235         $LCTL set_param -n llite.*.fast_read=1
20236         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20237                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20238                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20239         # small read with fast read disabled
20240         $LCTL set_param -n llite.*.fast_read=0
20241         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20242                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20243                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20244
20245         # verify that fast read is 4 times faster for cache read
20246         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20247                 error_not_in_vm "fast read was not 4 times faster: " \
20248                            "$t_fast vs $t_slow"
20249
20250         echo "Test 2: verify the performance between big and small read"
20251         $LCTL set_param -n llite.*.fast_read=1
20252
20253         # 1k non-cache read
20254         cancel_lru_locks osc
20255         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20256                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20257                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20258
20259         # 1M non-cache read
20260         cancel_lru_locks osc
20261         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20262                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20263                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20264
20265         # verify that big IO is not 4 times faster than small IO
20266         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20267                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20268
20269         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20270         rm -f $DIR/$tfile
20271 }
20272 run_test 248a "fast read verification"
20273
20274 test_248b() {
20275         # Default short_io_bytes=16384, try both smaller and larger sizes.
20276         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20277         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20278         echo "bs=53248 count=113 normal buffered write"
20279         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20280                 error "dd of initial data file failed"
20281         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20282
20283         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20284         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20285                 error "dd with sync normal writes failed"
20286         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20287
20288         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20289         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20290                 error "dd with sync small writes failed"
20291         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20292
20293         cancel_lru_locks osc
20294
20295         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20296         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20297         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20298         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20299                 iflag=direct || error "dd with O_DIRECT small read failed"
20300         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20301         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20302                 error "compare $TMP/$tfile.1 failed"
20303
20304         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20305         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20306
20307         # just to see what the maximum tunable value is, and test parsing
20308         echo "test invalid parameter 2MB"
20309         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20310                 error "too-large short_io_bytes allowed"
20311         echo "test maximum parameter 512KB"
20312         # if we can set a larger short_io_bytes, run test regardless of version
20313         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20314                 # older clients may not allow setting it this large, that's OK
20315                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20316                         skip "Need at least client version 2.13.50"
20317                 error "medium short_io_bytes failed"
20318         fi
20319         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20320         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20321
20322         echo "test large parameter 64KB"
20323         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20324         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20325
20326         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20327         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20328                 error "dd with sync large writes failed"
20329         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20330
20331         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20332         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20333         num=$((113 * 4096 / PAGE_SIZE))
20334         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20335         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20336                 error "dd with O_DIRECT large writes failed"
20337         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20338                 error "compare $DIR/$tfile.3 failed"
20339
20340         cancel_lru_locks osc
20341
20342         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20343         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20344                 error "dd with O_DIRECT large read failed"
20345         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20346                 error "compare $TMP/$tfile.2 failed"
20347
20348         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20349         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20350                 error "dd with O_DIRECT large read failed"
20351         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20352                 error "compare $TMP/$tfile.3 failed"
20353 }
20354 run_test 248b "test short_io read and write for both small and large sizes"
20355
20356 test_249() { # LU-7890
20357         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20358                 skip "Need at least version 2.8.54"
20359
20360         rm -f $DIR/$tfile
20361         $LFS setstripe -c 1 $DIR/$tfile
20362         # Offset 2T == 4k * 512M
20363         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20364                 error "dd to 2T offset failed"
20365 }
20366 run_test 249 "Write above 2T file size"
20367
20368 test_250() {
20369         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20370          && skip "no 16TB file size limit on ZFS"
20371
20372         $LFS setstripe -c 1 $DIR/$tfile
20373         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20374         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20375         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20376         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20377                 conv=notrunc,fsync && error "append succeeded"
20378         return 0
20379 }
20380 run_test 250 "Write above 16T limit"
20381
20382 test_251() {
20383         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20384
20385         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20386         #Skip once - writing the first stripe will succeed
20387         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20388         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20389                 error "short write happened"
20390
20391         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20392         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20393                 error "short read happened"
20394
20395         rm -f $DIR/$tfile
20396 }
20397 run_test 251 "Handling short read and write correctly"
20398
20399 test_252() {
20400         remote_mds_nodsh && skip "remote MDS with nodsh"
20401         remote_ost_nodsh && skip "remote OST with nodsh"
20402         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20403                 skip_env "ldiskfs only test"
20404         fi
20405
20406         local tgt
20407         local dev
20408         local out
20409         local uuid
20410         local num
20411         local gen
20412
20413         # check lr_reader on OST0000
20414         tgt=ost1
20415         dev=$(facet_device $tgt)
20416         out=$(do_facet $tgt $LR_READER $dev)
20417         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20418         echo "$out"
20419         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20420         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20421                 error "Invalid uuid returned by $LR_READER on target $tgt"
20422         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20423
20424         # check lr_reader -c on MDT0000
20425         tgt=mds1
20426         dev=$(facet_device $tgt)
20427         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20428                 skip "$LR_READER does not support additional options"
20429         fi
20430         out=$(do_facet $tgt $LR_READER -c $dev)
20431         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20432         echo "$out"
20433         num=$(echo "$out" | grep -c "mdtlov")
20434         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20435                 error "Invalid number of mdtlov clients returned by $LR_READER"
20436         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20437
20438         # check lr_reader -cr on MDT0000
20439         out=$(do_facet $tgt $LR_READER -cr $dev)
20440         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20441         echo "$out"
20442         echo "$out" | grep -q "^reply_data:$" ||
20443                 error "$LR_READER should have returned 'reply_data' section"
20444         num=$(echo "$out" | grep -c "client_generation")
20445         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20446 }
20447 run_test 252 "check lr_reader tool"
20448
20449 test_253() {
20450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20451         remote_mds_nodsh && skip "remote MDS with nodsh"
20452         remote_mgs_nodsh && skip "remote MGS with nodsh"
20453
20454         local ostidx=0
20455         local rc=0
20456         local ost_name=$(ostname_from_index $ostidx)
20457
20458         # on the mdt's osc
20459         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20460         do_facet $SINGLEMDS $LCTL get_param -n \
20461                 osp.$mdtosc_proc1.reserved_mb_high ||
20462                 skip  "remote MDS does not support reserved_mb_high"
20463
20464         rm -rf $DIR/$tdir
20465         wait_mds_ost_sync
20466         wait_delete_completed
20467         mkdir $DIR/$tdir
20468
20469         pool_add $TESTNAME || error "Pool creation failed"
20470         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20471
20472         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20473                 error "Setstripe failed"
20474
20475         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20476
20477         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20478                     grep "watermarks")
20479         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20480
20481         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20482                         osp.$mdtosc_proc1.prealloc_status)
20483         echo "prealloc_status $oa_status"
20484
20485         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20486                 error "File creation should fail"
20487
20488         #object allocation was stopped, but we still able to append files
20489         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20490                 oflag=append || error "Append failed"
20491
20492         rm -f $DIR/$tdir/$tfile.0
20493
20494         # For this test, we want to delete the files we created to go out of
20495         # space but leave the watermark, so we remain nearly out of space
20496         ost_watermarks_enospc_delete_files $tfile $ostidx
20497
20498         wait_delete_completed
20499
20500         sleep_maxage
20501
20502         for i in $(seq 10 12); do
20503                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20504                         2>/dev/null || error "File creation failed after rm"
20505         done
20506
20507         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20508                         osp.$mdtosc_proc1.prealloc_status)
20509         echo "prealloc_status $oa_status"
20510
20511         if (( oa_status != 0 )); then
20512                 error "Object allocation still disable after rm"
20513         fi
20514 }
20515 run_test 253 "Check object allocation limit"
20516
20517 test_254() {
20518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20519         remote_mds_nodsh && skip "remote MDS with nodsh"
20520         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20521                 skip "MDS does not support changelog_size"
20522
20523         local cl_user
20524         local MDT0=$(facet_svc $SINGLEMDS)
20525
20526         changelog_register || error "changelog_register failed"
20527
20528         changelog_clear 0 || error "changelog_clear failed"
20529
20530         local size1=$(do_facet $SINGLEMDS \
20531                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20532         echo "Changelog size $size1"
20533
20534         rm -rf $DIR/$tdir
20535         $LFS mkdir -i 0 $DIR/$tdir
20536         # change something
20537         mkdir -p $DIR/$tdir/pics/2008/zachy
20538         touch $DIR/$tdir/pics/2008/zachy/timestamp
20539         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20540         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20541         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20542         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20543         rm $DIR/$tdir/pics/desktop.jpg
20544
20545         local size2=$(do_facet $SINGLEMDS \
20546                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20547         echo "Changelog size after work $size2"
20548
20549         (( $size2 > $size1 )) ||
20550                 error "new Changelog size=$size2 less than old size=$size1"
20551 }
20552 run_test 254 "Check changelog size"
20553
20554 ladvise_no_type()
20555 {
20556         local type=$1
20557         local file=$2
20558
20559         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20560                 awk -F: '{print $2}' | grep $type > /dev/null
20561         if [ $? -ne 0 ]; then
20562                 return 0
20563         fi
20564         return 1
20565 }
20566
20567 ladvise_no_ioctl()
20568 {
20569         local file=$1
20570
20571         lfs ladvise -a willread $file > /dev/null 2>&1
20572         if [ $? -eq 0 ]; then
20573                 return 1
20574         fi
20575
20576         lfs ladvise -a willread $file 2>&1 |
20577                 grep "Inappropriate ioctl for device" > /dev/null
20578         if [ $? -eq 0 ]; then
20579                 return 0
20580         fi
20581         return 1
20582 }
20583
20584 percent() {
20585         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20586 }
20587
20588 # run a random read IO workload
20589 # usage: random_read_iops <filename> <filesize> <iosize>
20590 random_read_iops() {
20591         local file=$1
20592         local fsize=$2
20593         local iosize=${3:-4096}
20594
20595         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20596                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20597 }
20598
20599 drop_file_oss_cache() {
20600         local file="$1"
20601         local nodes="$2"
20602
20603         $LFS ladvise -a dontneed $file 2>/dev/null ||
20604                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20605 }
20606
20607 ladvise_willread_performance()
20608 {
20609         local repeat=10
20610         local average_origin=0
20611         local average_cache=0
20612         local average_ladvise=0
20613
20614         for ((i = 1; i <= $repeat; i++)); do
20615                 echo "Iter $i/$repeat: reading without willread hint"
20616                 cancel_lru_locks osc
20617                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20618                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20619                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20620                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20621
20622                 cancel_lru_locks osc
20623                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20624                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20625                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20626
20627                 cancel_lru_locks osc
20628                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20629                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20630                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20631                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20632                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20633         done
20634         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20635         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20636         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20637
20638         speedup_cache=$(percent $average_cache $average_origin)
20639         speedup_ladvise=$(percent $average_ladvise $average_origin)
20640
20641         echo "Average uncached read: $average_origin"
20642         echo "Average speedup with OSS cached read: " \
20643                 "$average_cache = +$speedup_cache%"
20644         echo "Average speedup with ladvise willread: " \
20645                 "$average_ladvise = +$speedup_ladvise%"
20646
20647         local lowest_speedup=20
20648         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20649                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20650                         "got $average_cache%. Skipping ladvise willread check."
20651                 return 0
20652         fi
20653
20654         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20655         # it is still good to run until then to exercise 'ladvise willread'
20656         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20657                 [ "$ost1_FSTYPE" = "zfs" ] &&
20658                 echo "osd-zfs does not support dontneed or drop_caches" &&
20659                 return 0
20660
20661         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20662         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20663                 error_not_in_vm "Speedup with willread is less than " \
20664                         "$lowest_speedup%, got $average_ladvise%"
20665 }
20666
20667 test_255a() {
20668         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20669                 skip "lustre < 2.8.54 does not support ladvise "
20670         remote_ost_nodsh && skip "remote OST with nodsh"
20671
20672         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20673
20674         ladvise_no_type willread $DIR/$tfile &&
20675                 skip "willread ladvise is not supported"
20676
20677         ladvise_no_ioctl $DIR/$tfile &&
20678                 skip "ladvise ioctl is not supported"
20679
20680         local size_mb=100
20681         local size=$((size_mb * 1048576))
20682         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20683                 error "dd to $DIR/$tfile failed"
20684
20685         lfs ladvise -a willread $DIR/$tfile ||
20686                 error "Ladvise failed with no range argument"
20687
20688         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20689                 error "Ladvise failed with no -l or -e argument"
20690
20691         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20692                 error "Ladvise failed with only -e argument"
20693
20694         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20695                 error "Ladvise failed with only -l argument"
20696
20697         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20698                 error "End offset should not be smaller than start offset"
20699
20700         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20701                 error "End offset should not be equal to start offset"
20702
20703         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20704                 error "Ladvise failed with overflowing -s argument"
20705
20706         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20707                 error "Ladvise failed with overflowing -e argument"
20708
20709         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20710                 error "Ladvise failed with overflowing -l argument"
20711
20712         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20713                 error "Ladvise succeeded with conflicting -l and -e arguments"
20714
20715         echo "Synchronous ladvise should wait"
20716         local delay=4
20717 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20718         do_nodes $(comma_list $(osts_nodes)) \
20719                 $LCTL set_param fail_val=$delay fail_loc=0x237
20720
20721         local start_ts=$SECONDS
20722         lfs ladvise -a willread $DIR/$tfile ||
20723                 error "Ladvise failed with no range argument"
20724         local end_ts=$SECONDS
20725         local inteval_ts=$((end_ts - start_ts))
20726
20727         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20728                 error "Synchronous advice didn't wait reply"
20729         fi
20730
20731         echo "Asynchronous ladvise shouldn't wait"
20732         local start_ts=$SECONDS
20733         lfs ladvise -a willread -b $DIR/$tfile ||
20734                 error "Ladvise failed with no range argument"
20735         local end_ts=$SECONDS
20736         local inteval_ts=$((end_ts - start_ts))
20737
20738         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20739                 error "Asynchronous advice blocked"
20740         fi
20741
20742         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20743         ladvise_willread_performance
20744 }
20745 run_test 255a "check 'lfs ladvise -a willread'"
20746
20747 facet_meminfo() {
20748         local facet=$1
20749         local info=$2
20750
20751         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20752 }
20753
20754 test_255b() {
20755         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20756                 skip "lustre < 2.8.54 does not support ladvise "
20757         remote_ost_nodsh && skip "remote OST with nodsh"
20758
20759         lfs setstripe -c 1 -i 0 $DIR/$tfile
20760
20761         ladvise_no_type dontneed $DIR/$tfile &&
20762                 skip "dontneed ladvise is not supported"
20763
20764         ladvise_no_ioctl $DIR/$tfile &&
20765                 skip "ladvise ioctl is not supported"
20766
20767         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20768                 [ "$ost1_FSTYPE" = "zfs" ] &&
20769                 skip "zfs-osd does not support 'ladvise dontneed'"
20770
20771         local size_mb=100
20772         local size=$((size_mb * 1048576))
20773         # In order to prevent disturbance of other processes, only check 3/4
20774         # of the memory usage
20775         local kibibytes=$((size_mb * 1024 * 3 / 4))
20776
20777         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20778                 error "dd to $DIR/$tfile failed"
20779
20780         #force write to complete before dropping OST cache & checking memory
20781         sync
20782
20783         local total=$(facet_meminfo ost1 MemTotal)
20784         echo "Total memory: $total KiB"
20785
20786         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20787         local before_read=$(facet_meminfo ost1 Cached)
20788         echo "Cache used before read: $before_read KiB"
20789
20790         lfs ladvise -a willread $DIR/$tfile ||
20791                 error "Ladvise willread failed"
20792         local after_read=$(facet_meminfo ost1 Cached)
20793         echo "Cache used after read: $after_read KiB"
20794
20795         lfs ladvise -a dontneed $DIR/$tfile ||
20796                 error "Ladvise dontneed again failed"
20797         local no_read=$(facet_meminfo ost1 Cached)
20798         echo "Cache used after dontneed ladvise: $no_read KiB"
20799
20800         if [ $total -lt $((before_read + kibibytes)) ]; then
20801                 echo "Memory is too small, abort checking"
20802                 return 0
20803         fi
20804
20805         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20806                 error "Ladvise willread should use more memory" \
20807                         "than $kibibytes KiB"
20808         fi
20809
20810         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20811                 error "Ladvise dontneed should release more memory" \
20812                         "than $kibibytes KiB"
20813         fi
20814 }
20815 run_test 255b "check 'lfs ladvise -a dontneed'"
20816
20817 test_255c() {
20818         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20819                 skip "lustre < 2.10.50 does not support lockahead"
20820
20821         local ost1_imp=$(get_osc_import_name client ost1)
20822         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20823                          cut -d'.' -f2)
20824         local count
20825         local new_count
20826         local difference
20827         local i
20828         local rc
20829
20830         test_mkdir -p $DIR/$tdir
20831         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20832
20833         #test 10 returns only success/failure
20834         i=10
20835         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20836         rc=$?
20837         if [ $rc -eq 255 ]; then
20838                 error "Ladvise test${i} failed, ${rc}"
20839         fi
20840
20841         #test 11 counts lock enqueue requests, all others count new locks
20842         i=11
20843         count=$(do_facet ost1 \
20844                 $LCTL get_param -n ost.OSS.ost.stats)
20845         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20846
20847         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20848         rc=$?
20849         if [ $rc -eq 255 ]; then
20850                 error "Ladvise test${i} failed, ${rc}"
20851         fi
20852
20853         new_count=$(do_facet ost1 \
20854                 $LCTL get_param -n ost.OSS.ost.stats)
20855         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20856                    awk '{ print $2 }')
20857
20858         difference="$((new_count - count))"
20859         if [ $difference -ne $rc ]; then
20860                 error "Ladvise test${i}, bad enqueue count, returned " \
20861                       "${rc}, actual ${difference}"
20862         fi
20863
20864         for i in $(seq 12 21); do
20865                 # If we do not do this, we run the risk of having too many
20866                 # locks and starting lock cancellation while we are checking
20867                 # lock counts.
20868                 cancel_lru_locks osc
20869
20870                 count=$($LCTL get_param -n \
20871                        ldlm.namespaces.$imp_name.lock_unused_count)
20872
20873                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20874                 rc=$?
20875                 if [ $rc -eq 255 ]; then
20876                         error "Ladvise test ${i} failed, ${rc}"
20877                 fi
20878
20879                 new_count=$($LCTL get_param -n \
20880                        ldlm.namespaces.$imp_name.lock_unused_count)
20881                 difference="$((new_count - count))"
20882
20883                 # Test 15 output is divided by 100 to map down to valid return
20884                 if [ $i -eq 15 ]; then
20885                         rc="$((rc * 100))"
20886                 fi
20887
20888                 if [ $difference -ne $rc ]; then
20889                         error "Ladvise test ${i}, bad lock count, returned " \
20890                               "${rc}, actual ${difference}"
20891                 fi
20892         done
20893
20894         #test 22 returns only success/failure
20895         i=22
20896         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20897         rc=$?
20898         if [ $rc -eq 255 ]; then
20899                 error "Ladvise test${i} failed, ${rc}"
20900         fi
20901 }
20902 run_test 255c "suite of ladvise lockahead tests"
20903
20904 test_256() {
20905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20906         remote_mds_nodsh && skip "remote MDS with nodsh"
20907         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20908         changelog_users $SINGLEMDS | grep "^cl" &&
20909                 skip "active changelog user"
20910
20911         local cl_user
20912         local cat_sl
20913         local mdt_dev
20914
20915         mdt_dev=$(mdsdevname 1)
20916         echo $mdt_dev
20917
20918         changelog_register || error "changelog_register failed"
20919
20920         rm -rf $DIR/$tdir
20921         mkdir -p $DIR/$tdir
20922
20923         changelog_clear 0 || error "changelog_clear failed"
20924
20925         # change something
20926         touch $DIR/$tdir/{1..10}
20927
20928         # stop the MDT
20929         stop $SINGLEMDS || error "Fail to stop MDT"
20930
20931         # remount the MDT
20932
20933         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20934
20935         #after mount new plainllog is used
20936         touch $DIR/$tdir/{11..19}
20937         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20938         stack_trap "rm -f $tmpfile"
20939         cat_sl=$(do_facet $SINGLEMDS "sync; \
20940                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20941                  llog_reader $tmpfile | grep -c type=1064553b")
20942         do_facet $SINGLEMDS llog_reader $tmpfile
20943
20944         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20945
20946         changelog_clear 0 || error "changelog_clear failed"
20947
20948         cat_sl=$(do_facet $SINGLEMDS "sync; \
20949                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20950                  llog_reader $tmpfile | grep -c type=1064553b")
20951
20952         if (( cat_sl == 2 )); then
20953                 error "Empty plain llog was not deleted from changelog catalog"
20954         elif (( cat_sl != 1 )); then
20955                 error "Active plain llog shouldn't be deleted from catalog"
20956         fi
20957 }
20958 run_test 256 "Check llog delete for empty and not full state"
20959
20960 test_257() {
20961         remote_mds_nodsh && skip "remote MDS with nodsh"
20962         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20963                 skip "Need MDS version at least 2.8.55"
20964
20965         test_mkdir $DIR/$tdir
20966
20967         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20968                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20969         stat $DIR/$tdir
20970
20971 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20972         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20973         local facet=mds$((mdtidx + 1))
20974         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20975         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20976
20977         stop $facet || error "stop MDS failed"
20978         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20979                 error "start MDS fail"
20980         wait_recovery_complete $facet
20981 }
20982 run_test 257 "xattr locks are not lost"
20983
20984 # Verify we take the i_mutex when security requires it
20985 test_258a() {
20986 #define OBD_FAIL_IMUTEX_SEC 0x141c
20987         $LCTL set_param fail_loc=0x141c
20988         touch $DIR/$tfile
20989         chmod u+s $DIR/$tfile
20990         chmod a+rwx $DIR/$tfile
20991         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20992         RC=$?
20993         if [ $RC -ne 0 ]; then
20994                 error "error, failed to take i_mutex, rc=$?"
20995         fi
20996         rm -f $DIR/$tfile
20997 }
20998 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20999
21000 # Verify we do NOT take the i_mutex in the normal case
21001 test_258b() {
21002 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21003         $LCTL set_param fail_loc=0x141d
21004         touch $DIR/$tfile
21005         chmod a+rwx $DIR
21006         chmod a+rw $DIR/$tfile
21007         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21008         RC=$?
21009         if [ $RC -ne 0 ]; then
21010                 error "error, took i_mutex unnecessarily, rc=$?"
21011         fi
21012         rm -f $DIR/$tfile
21013
21014 }
21015 run_test 258b "verify i_mutex security behavior"
21016
21017 test_259() {
21018         local file=$DIR/$tfile
21019         local before
21020         local after
21021
21022         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21023
21024         stack_trap "rm -f $file" EXIT
21025
21026         wait_delete_completed
21027         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21028         echo "before: $before"
21029
21030         $LFS setstripe -i 0 -c 1 $file
21031         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21032         sync_all_data
21033         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21034         echo "after write: $after"
21035
21036 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21037         do_facet ost1 $LCTL set_param fail_loc=0x2301
21038         $TRUNCATE $file 0
21039         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21040         echo "after truncate: $after"
21041
21042         stop ost1
21043         do_facet ost1 $LCTL set_param fail_loc=0
21044         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21045         sleep 2
21046         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21047         echo "after restart: $after"
21048         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21049                 error "missing truncate?"
21050
21051         return 0
21052 }
21053 run_test 259 "crash at delayed truncate"
21054
21055 test_260() {
21056 #define OBD_FAIL_MDC_CLOSE               0x806
21057         $LCTL set_param fail_loc=0x80000806
21058         touch $DIR/$tfile
21059
21060 }
21061 run_test 260 "Check mdc_close fail"
21062
21063 ### Data-on-MDT sanity tests ###
21064 test_270a() {
21065         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21066                 skip "Need MDS version at least 2.10.55 for DoM"
21067
21068         # create DoM file
21069         local dom=$DIR/$tdir/dom_file
21070         local tmp=$DIR/$tdir/tmp_file
21071
21072         mkdir -p $DIR/$tdir
21073
21074         # basic checks for DoM component creation
21075         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21076                 error "Can set MDT layout to non-first entry"
21077
21078         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21079                 error "Can define multiple entries as MDT layout"
21080
21081         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21082
21083         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21084         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21085         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21086
21087         local mdtidx=$($LFS getstripe -m $dom)
21088         local mdtname=MDT$(printf %04x $mdtidx)
21089         local facet=mds$((mdtidx + 1))
21090         local space_check=1
21091
21092         # Skip free space checks with ZFS
21093         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21094
21095         # write
21096         sync
21097         local size_tmp=$((65536 * 3))
21098         local mdtfree1=$(do_facet $facet \
21099                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21100
21101         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21102         # check also direct IO along write
21103         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21104         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21105         sync
21106         cmp $tmp $dom || error "file data is different"
21107         [ $(stat -c%s $dom) == $size_tmp ] ||
21108                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21109         if [ $space_check == 1 ]; then
21110                 local mdtfree2=$(do_facet $facet \
21111                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21112
21113                 # increase in usage from by $size_tmp
21114                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21115                         error "MDT free space wrong after write: " \
21116                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21117         fi
21118
21119         # truncate
21120         local size_dom=10000
21121
21122         $TRUNCATE $dom $size_dom
21123         [ $(stat -c%s $dom) == $size_dom ] ||
21124                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21125         if [ $space_check == 1 ]; then
21126                 mdtfree1=$(do_facet $facet \
21127                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21128                 # decrease in usage from $size_tmp to new $size_dom
21129                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21130                   $(((size_tmp - size_dom) / 1024)) ] ||
21131                         error "MDT free space is wrong after truncate: " \
21132                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21133         fi
21134
21135         # append
21136         cat $tmp >> $dom
21137         sync
21138         size_dom=$((size_dom + size_tmp))
21139         [ $(stat -c%s $dom) == $size_dom ] ||
21140                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21141         if [ $space_check == 1 ]; then
21142                 mdtfree2=$(do_facet $facet \
21143                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21144                 # increase in usage by $size_tmp from previous
21145                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21146                         error "MDT free space is wrong after append: " \
21147                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21148         fi
21149
21150         # delete
21151         rm $dom
21152         if [ $space_check == 1 ]; then
21153                 mdtfree1=$(do_facet $facet \
21154                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21155                 # decrease in usage by $size_dom from previous
21156                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21157                         error "MDT free space is wrong after removal: " \
21158                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21159         fi
21160
21161         # combined striping
21162         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21163                 error "Can't create DoM + OST striping"
21164
21165         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21166         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21167         # check also direct IO along write
21168         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21169         sync
21170         cmp $tmp $dom || error "file data is different"
21171         [ $(stat -c%s $dom) == $size_tmp ] ||
21172                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21173         rm $dom $tmp
21174
21175         return 0
21176 }
21177 run_test 270a "DoM: basic functionality tests"
21178
21179 test_270b() {
21180         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21181                 skip "Need MDS version at least 2.10.55"
21182
21183         local dom=$DIR/$tdir/dom_file
21184         local max_size=1048576
21185
21186         mkdir -p $DIR/$tdir
21187         $LFS setstripe -E $max_size -L mdt $dom
21188
21189         # truncate over the limit
21190         $TRUNCATE $dom $(($max_size + 1)) &&
21191                 error "successful truncate over the maximum size"
21192         # write over the limit
21193         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21194                 error "successful write over the maximum size"
21195         # append over the limit
21196         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21197         echo "12345" >> $dom && error "successful append over the maximum size"
21198         rm $dom
21199
21200         return 0
21201 }
21202 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21203
21204 test_270c() {
21205         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21206                 skip "Need MDS version at least 2.10.55"
21207
21208         mkdir -p $DIR/$tdir
21209         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21210
21211         # check files inherit DoM EA
21212         touch $DIR/$tdir/first
21213         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21214                 error "bad pattern"
21215         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21216                 error "bad stripe count"
21217         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21218                 error "bad stripe size"
21219
21220         # check directory inherits DoM EA and uses it as default
21221         mkdir $DIR/$tdir/subdir
21222         touch $DIR/$tdir/subdir/second
21223         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21224                 error "bad pattern in sub-directory"
21225         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21226                 error "bad stripe count in sub-directory"
21227         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21228                 error "bad stripe size in sub-directory"
21229         return 0
21230 }
21231 run_test 270c "DoM: DoM EA inheritance tests"
21232
21233 test_270d() {
21234         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21235                 skip "Need MDS version at least 2.10.55"
21236
21237         mkdir -p $DIR/$tdir
21238         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21239
21240         # inherit default DoM striping
21241         mkdir $DIR/$tdir/subdir
21242         touch $DIR/$tdir/subdir/f1
21243
21244         # change default directory striping
21245         $LFS setstripe -c 1 $DIR/$tdir/subdir
21246         touch $DIR/$tdir/subdir/f2
21247         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21248                 error "wrong default striping in file 2"
21249         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21250                 error "bad pattern in file 2"
21251         return 0
21252 }
21253 run_test 270d "DoM: change striping from DoM to RAID0"
21254
21255 test_270e() {
21256         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21257                 skip "Need MDS version at least 2.10.55"
21258
21259         mkdir -p $DIR/$tdir/dom
21260         mkdir -p $DIR/$tdir/norm
21261         DOMFILES=20
21262         NORMFILES=10
21263         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21264         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21265
21266         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21267         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21268
21269         # find DoM files by layout
21270         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21271         [ $NUM -eq  $DOMFILES ] ||
21272                 error "lfs find -L: found $NUM, expected $DOMFILES"
21273         echo "Test 1: lfs find 20 DOM files by layout: OK"
21274
21275         # there should be 1 dir with default DOM striping
21276         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21277         [ $NUM -eq  1 ] ||
21278                 error "lfs find -L: found $NUM, expected 1 dir"
21279         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21280
21281         # find DoM files by stripe size
21282         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21283         [ $NUM -eq  $DOMFILES ] ||
21284                 error "lfs find -S: found $NUM, expected $DOMFILES"
21285         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21286
21287         # find files by stripe offset except DoM files
21288         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21289         [ $NUM -eq  $NORMFILES ] ||
21290                 error "lfs find -i: found $NUM, expected $NORMFILES"
21291         echo "Test 5: lfs find no DOM files by stripe index: OK"
21292         return 0
21293 }
21294 run_test 270e "DoM: lfs find with DoM files test"
21295
21296 test_270f() {
21297         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21298                 skip "Need MDS version at least 2.10.55"
21299
21300         local mdtname=${FSNAME}-MDT0000-mdtlov
21301         local dom=$DIR/$tdir/dom_file
21302         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21303                                                 lod.$mdtname.dom_stripesize)
21304         local dom_limit=131072
21305
21306         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21307         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21308                                                 lod.$mdtname.dom_stripesize)
21309         [ ${dom_limit} -eq ${dom_current} ] ||
21310                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21311
21312         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21313         $LFS setstripe -d $DIR/$tdir
21314         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21315                 error "Can't set directory default striping"
21316
21317         # exceed maximum stripe size
21318         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21319                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21320         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21321                 error "Able to create DoM component size more than LOD limit"
21322
21323         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21324         dom_current=$(do_facet mds1 $LCTL get_param -n \
21325                                                 lod.$mdtname.dom_stripesize)
21326         [ 0 -eq ${dom_current} ] ||
21327                 error "Can't set zero DoM stripe limit"
21328         rm $dom
21329
21330         # attempt to create DoM file on server with disabled DoM should
21331         # remove DoM entry from layout and be succeed
21332         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21333                 error "Can't create DoM file (DoM is disabled)"
21334         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21335                 error "File has DoM component while DoM is disabled"
21336         rm $dom
21337
21338         # attempt to create DoM file with only DoM stripe should return error
21339         $LFS setstripe -E $dom_limit -L mdt $dom &&
21340                 error "Able to create DoM-only file while DoM is disabled"
21341
21342         # too low values to be aligned with smallest stripe size 64K
21343         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21344         dom_current=$(do_facet mds1 $LCTL get_param -n \
21345                                                 lod.$mdtname.dom_stripesize)
21346         [ 30000 -eq ${dom_current} ] &&
21347                 error "Can set too small DoM stripe limit"
21348
21349         # 64K is a minimal stripe size in Lustre, expect limit of that size
21350         [ 65536 -eq ${dom_current} ] ||
21351                 error "Limit is not set to 64K but ${dom_current}"
21352
21353         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21354         dom_current=$(do_facet mds1 $LCTL get_param -n \
21355                                                 lod.$mdtname.dom_stripesize)
21356         echo $dom_current
21357         [ 2147483648 -eq ${dom_current} ] &&
21358                 error "Can set too large DoM stripe limit"
21359
21360         do_facet mds1 $LCTL set_param -n \
21361                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21362         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21363                 error "Can't create DoM component size after limit change"
21364         do_facet mds1 $LCTL set_param -n \
21365                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21366         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21367                 error "Can't create DoM file after limit decrease"
21368         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21369                 error "Can create big DoM component after limit decrease"
21370         touch ${dom}_def ||
21371                 error "Can't create file with old default layout"
21372
21373         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21374         return 0
21375 }
21376 run_test 270f "DoM: maximum DoM stripe size checks"
21377
21378 test_270g() {
21379         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21380                 skip "Need MDS version at least 2.13.52"
21381         local dom=$DIR/$tdir/$tfile
21382
21383         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21384         local lodname=${FSNAME}-MDT0000-mdtlov
21385
21386         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21387         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21388         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21389         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21390
21391         local dom_limit=1024
21392         local dom_threshold="50%"
21393
21394         $LFS setstripe -d $DIR/$tdir
21395         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21396                 error "Can't set directory default striping"
21397
21398         do_facet mds1 $LCTL set_param -n \
21399                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21400         # set 0 threshold and create DOM file to change tunable stripesize
21401         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21402         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21403                 error "Failed to create $dom file"
21404         # now tunable dom_cur_stripesize should reach maximum
21405         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21406                                         lod.${lodname}.dom_stripesize_cur_kb)
21407         [[ $dom_current == $dom_limit ]] ||
21408                 error "Current DOM stripesize is not maximum"
21409         rm $dom
21410
21411         # set threshold for further tests
21412         do_facet mds1 $LCTL set_param -n \
21413                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21414         echo "DOM threshold is $dom_threshold free space"
21415         local dom_def
21416         local dom_set
21417         # Spoof bfree to exceed threshold
21418         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21419         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21420         for spfree in 40 20 0 15 30 55; do
21421                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21422                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21423                         error "Failed to create $dom file"
21424                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21425                                         lod.${lodname}.dom_stripesize_cur_kb)
21426                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21427                 [[ $dom_def != $dom_current ]] ||
21428                         error "Default stripe size was not changed"
21429                 if [[ $spfree > 0 ]] ; then
21430                         dom_set=$($LFS getstripe -S $dom)
21431                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21432                                 error "DOM component size is still old"
21433                 else
21434                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21435                                 error "DoM component is set with no free space"
21436                 fi
21437                 rm $dom
21438                 dom_current=$dom_def
21439         done
21440 }
21441 run_test 270g "DoM: default DoM stripe size depends on free space"
21442
21443 test_270h() {
21444         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21445                 skip "Need MDS version at least 2.13.53"
21446
21447         local mdtname=${FSNAME}-MDT0000-mdtlov
21448         local dom=$DIR/$tdir/$tfile
21449         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21450
21451         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21452         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21453
21454         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21455         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21456                 error "can't create OST file"
21457         # mirrored file with DOM entry in the second mirror
21458         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21459                 error "can't create mirror with DoM component"
21460
21461         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21462
21463         # DOM component in the middle and has other enries in the same mirror,
21464         # should succeed but lost DoM component
21465         $LFS setstripe --copy=${dom}_1 $dom ||
21466                 error "Can't create file from OST|DOM mirror layout"
21467         # check new file has no DoM layout after all
21468         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21469                 error "File has DoM component while DoM is disabled"
21470 }
21471 run_test 270h "DoM: DoM stripe removal when disabled on server"
21472
21473 test_271a() {
21474         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21475                 skip "Need MDS version at least 2.10.55"
21476
21477         local dom=$DIR/$tdir/dom
21478
21479         mkdir -p $DIR/$tdir
21480
21481         $LFS setstripe -E 1024K -L mdt $dom
21482
21483         lctl set_param -n mdc.*.stats=clear
21484         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21485         cat $dom > /dev/null
21486         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21487         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21488         ls $dom
21489         rm -f $dom
21490 }
21491 run_test 271a "DoM: data is cached for read after write"
21492
21493 test_271b() {
21494         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21495                 skip "Need MDS version at least 2.10.55"
21496
21497         local dom=$DIR/$tdir/dom
21498
21499         mkdir -p $DIR/$tdir
21500
21501         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21502
21503         lctl set_param -n mdc.*.stats=clear
21504         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21505         cancel_lru_locks mdc
21506         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21507         # second stat to check size is cached on client
21508         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21509         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21510         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21511         rm -f $dom
21512 }
21513 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21514
21515 test_271ba() {
21516         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21517                 skip "Need MDS version at least 2.10.55"
21518
21519         local dom=$DIR/$tdir/dom
21520
21521         mkdir -p $DIR/$tdir
21522
21523         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21524
21525         lctl set_param -n mdc.*.stats=clear
21526         lctl set_param -n osc.*.stats=clear
21527         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21528         cancel_lru_locks mdc
21529         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21530         # second stat to check size is cached on client
21531         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21532         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21533         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21534         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21535         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21536         rm -f $dom
21537 }
21538 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21539
21540
21541 get_mdc_stats() {
21542         local mdtidx=$1
21543         local param=$2
21544         local mdt=MDT$(printf %04x $mdtidx)
21545
21546         if [ -z $param ]; then
21547                 lctl get_param -n mdc.*$mdt*.stats
21548         else
21549                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21550         fi
21551 }
21552
21553 test_271c() {
21554         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21555                 skip "Need MDS version at least 2.10.55"
21556
21557         local dom=$DIR/$tdir/dom
21558
21559         mkdir -p $DIR/$tdir
21560
21561         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21562
21563         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21564         local facet=mds$((mdtidx + 1))
21565
21566         cancel_lru_locks mdc
21567         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21568         createmany -o $dom 1000
21569         lctl set_param -n mdc.*.stats=clear
21570         smalliomany -w $dom 1000 200
21571         get_mdc_stats $mdtidx
21572         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21573         # Each file has 1 open, 1 IO enqueues, total 2000
21574         # but now we have also +1 getxattr for security.capability, total 3000
21575         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21576         unlinkmany $dom 1000
21577
21578         cancel_lru_locks mdc
21579         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21580         createmany -o $dom 1000
21581         lctl set_param -n mdc.*.stats=clear
21582         smalliomany -w $dom 1000 200
21583         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21584         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21585         # for OPEN and IO lock.
21586         [ $((enq - enq_2)) -ge 1000 ] ||
21587                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21588         unlinkmany $dom 1000
21589         return 0
21590 }
21591 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21592
21593 cleanup_271def_tests() {
21594         trap 0
21595         rm -f $1
21596 }
21597
21598 test_271d() {
21599         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21600                 skip "Need MDS version at least 2.10.57"
21601
21602         local dom=$DIR/$tdir/dom
21603         local tmp=$TMP/$tfile
21604         trap "cleanup_271def_tests $tmp" EXIT
21605
21606         mkdir -p $DIR/$tdir
21607
21608         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21609
21610         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21611
21612         cancel_lru_locks mdc
21613         dd if=/dev/urandom of=$tmp bs=1000 count=1
21614         dd if=$tmp of=$dom bs=1000 count=1
21615         cancel_lru_locks mdc
21616
21617         cat /etc/hosts >> $tmp
21618         lctl set_param -n mdc.*.stats=clear
21619
21620         # append data to the same file it should update local page
21621         echo "Append to the same page"
21622         cat /etc/hosts >> $dom
21623         local num=$(get_mdc_stats $mdtidx ost_read)
21624         local ra=$(get_mdc_stats $mdtidx req_active)
21625         local rw=$(get_mdc_stats $mdtidx req_waittime)
21626
21627         [ -z $num ] || error "$num READ RPC occured"
21628         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21629         echo "... DONE"
21630
21631         # compare content
21632         cmp $tmp $dom || error "file miscompare"
21633
21634         cancel_lru_locks mdc
21635         lctl set_param -n mdc.*.stats=clear
21636
21637         echo "Open and read file"
21638         cat $dom > /dev/null
21639         local num=$(get_mdc_stats $mdtidx ost_read)
21640         local ra=$(get_mdc_stats $mdtidx req_active)
21641         local rw=$(get_mdc_stats $mdtidx req_waittime)
21642
21643         [ -z $num ] || error "$num READ RPC occured"
21644         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21645         echo "... DONE"
21646
21647         # compare content
21648         cmp $tmp $dom || error "file miscompare"
21649
21650         return 0
21651 }
21652 run_test 271d "DoM: read on open (1K file in reply buffer)"
21653
21654 test_271f() {
21655         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21656                 skip "Need MDS version at least 2.10.57"
21657
21658         local dom=$DIR/$tdir/dom
21659         local tmp=$TMP/$tfile
21660         trap "cleanup_271def_tests $tmp" EXIT
21661
21662         mkdir -p $DIR/$tdir
21663
21664         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21665
21666         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21667
21668         cancel_lru_locks mdc
21669         dd if=/dev/urandom of=$tmp bs=265000 count=1
21670         dd if=$tmp of=$dom bs=265000 count=1
21671         cancel_lru_locks mdc
21672         cat /etc/hosts >> $tmp
21673         lctl set_param -n mdc.*.stats=clear
21674
21675         echo "Append to the same page"
21676         cat /etc/hosts >> $dom
21677         local num=$(get_mdc_stats $mdtidx ost_read)
21678         local ra=$(get_mdc_stats $mdtidx req_active)
21679         local rw=$(get_mdc_stats $mdtidx req_waittime)
21680
21681         [ -z $num ] || error "$num READ RPC occured"
21682         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21683         echo "... DONE"
21684
21685         # compare content
21686         cmp $tmp $dom || error "file miscompare"
21687
21688         cancel_lru_locks mdc
21689         lctl set_param -n mdc.*.stats=clear
21690
21691         echo "Open and read file"
21692         cat $dom > /dev/null
21693         local num=$(get_mdc_stats $mdtidx ost_read)
21694         local ra=$(get_mdc_stats $mdtidx req_active)
21695         local rw=$(get_mdc_stats $mdtidx req_waittime)
21696
21697         [ -z $num ] && num=0
21698         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21699         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21700         echo "... DONE"
21701
21702         # compare content
21703         cmp $tmp $dom || error "file miscompare"
21704
21705         return 0
21706 }
21707 run_test 271f "DoM: read on open (200K file and read tail)"
21708
21709 test_271g() {
21710         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21711                 skip "Skipping due to old client or server version"
21712
21713         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21714         # to get layout
21715         $CHECKSTAT -t file $DIR1/$tfile
21716
21717         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21718         MULTIOP_PID=$!
21719         sleep 1
21720         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21721         $LCTL set_param fail_loc=0x80000314
21722         rm $DIR1/$tfile || error "Unlink fails"
21723         RC=$?
21724         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21725         [ $RC -eq 0 ] || error "Failed write to stale object"
21726 }
21727 run_test 271g "Discard DoM data vs client flush race"
21728
21729 test_272a() {
21730         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21731                 skip "Need MDS version at least 2.11.50"
21732
21733         local dom=$DIR/$tdir/dom
21734         mkdir -p $DIR/$tdir
21735
21736         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21737         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21738                 error "failed to write data into $dom"
21739         local old_md5=$(md5sum $dom)
21740
21741         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21742                 error "failed to migrate to the same DoM component"
21743
21744         local new_md5=$(md5sum $dom)
21745
21746         [ "$old_md5" == "$new_md5" ] ||
21747                 error "md5sum differ: $old_md5, $new_md5"
21748
21749         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21750                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21751 }
21752 run_test 272a "DoM migration: new layout with the same DOM component"
21753
21754 test_272b() {
21755         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21756                 skip "Need MDS version at least 2.11.50"
21757
21758         local dom=$DIR/$tdir/dom
21759         mkdir -p $DIR/$tdir
21760         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21761
21762         local mdtidx=$($LFS getstripe -m $dom)
21763         local mdtname=MDT$(printf %04x $mdtidx)
21764         local facet=mds$((mdtidx + 1))
21765
21766         local mdtfree1=$(do_facet $facet \
21767                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21768         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21769                 error "failed to write data into $dom"
21770         local old_md5=$(md5sum $dom)
21771         cancel_lru_locks mdc
21772         local mdtfree1=$(do_facet $facet \
21773                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21774
21775         $LFS migrate -c2 $dom ||
21776                 error "failed to migrate to the new composite layout"
21777         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21778                 error "MDT stripe was not removed"
21779
21780         cancel_lru_locks mdc
21781         local new_md5=$(md5sum $dom)
21782         [ "$old_md5" == "$new_md5" ] ||
21783                 error "$old_md5 != $new_md5"
21784
21785         # Skip free space checks with ZFS
21786         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21787                 local mdtfree2=$(do_facet $facet \
21788                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21789                 [ $mdtfree2 -gt $mdtfree1 ] ||
21790                         error "MDT space is not freed after migration"
21791         fi
21792         return 0
21793 }
21794 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21795
21796 test_272c() {
21797         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21798                 skip "Need MDS version at least 2.11.50"
21799
21800         local dom=$DIR/$tdir/$tfile
21801         mkdir -p $DIR/$tdir
21802         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21803
21804         local mdtidx=$($LFS getstripe -m $dom)
21805         local mdtname=MDT$(printf %04x $mdtidx)
21806         local facet=mds$((mdtidx + 1))
21807
21808         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21809                 error "failed to write data into $dom"
21810         local old_md5=$(md5sum $dom)
21811         cancel_lru_locks mdc
21812         local mdtfree1=$(do_facet $facet \
21813                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21814
21815         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21816                 error "failed to migrate to the new composite layout"
21817         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21818                 error "MDT stripe was not removed"
21819
21820         cancel_lru_locks mdc
21821         local new_md5=$(md5sum $dom)
21822         [ "$old_md5" == "$new_md5" ] ||
21823                 error "$old_md5 != $new_md5"
21824
21825         # Skip free space checks with ZFS
21826         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21827                 local mdtfree2=$(do_facet $facet \
21828                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21829                 [ $mdtfree2 -gt $mdtfree1 ] ||
21830                         error "MDS space is not freed after migration"
21831         fi
21832         return 0
21833 }
21834 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21835
21836 test_272d() {
21837         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21838                 skip "Need MDS version at least 2.12.55"
21839
21840         local dom=$DIR/$tdir/$tfile
21841         mkdir -p $DIR/$tdir
21842         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21843
21844         local mdtidx=$($LFS getstripe -m $dom)
21845         local mdtname=MDT$(printf %04x $mdtidx)
21846         local facet=mds$((mdtidx + 1))
21847
21848         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21849                 error "failed to write data into $dom"
21850         local old_md5=$(md5sum $dom)
21851         cancel_lru_locks mdc
21852         local mdtfree1=$(do_facet $facet \
21853                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21854
21855         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21856                 error "failed mirroring to the new composite layout"
21857         $LFS mirror resync $dom ||
21858                 error "failed mirror resync"
21859         $LFS mirror split --mirror-id 1 -d $dom ||
21860                 error "failed mirror split"
21861
21862         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21863                 error "MDT stripe was not removed"
21864
21865         cancel_lru_locks mdc
21866         local new_md5=$(md5sum $dom)
21867         [ "$old_md5" == "$new_md5" ] ||
21868                 error "$old_md5 != $new_md5"
21869
21870         # Skip free space checks with ZFS
21871         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21872                 local mdtfree2=$(do_facet $facet \
21873                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21874                 [ $mdtfree2 -gt $mdtfree1 ] ||
21875                         error "MDS space is not freed after DOM mirror deletion"
21876         fi
21877         return 0
21878 }
21879 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21880
21881 test_272e() {
21882         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21883                 skip "Need MDS version at least 2.12.55"
21884
21885         local dom=$DIR/$tdir/$tfile
21886         mkdir -p $DIR/$tdir
21887         $LFS setstripe -c 2 $dom
21888
21889         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21890                 error "failed to write data into $dom"
21891         local old_md5=$(md5sum $dom)
21892         cancel_lru_locks mdc
21893
21894         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21895                 error "failed mirroring to the DOM layout"
21896         $LFS mirror resync $dom ||
21897                 error "failed mirror resync"
21898         $LFS mirror split --mirror-id 1 -d $dom ||
21899                 error "failed mirror split"
21900
21901         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21902                 error "MDT stripe was not removed"
21903
21904         cancel_lru_locks mdc
21905         local new_md5=$(md5sum $dom)
21906         [ "$old_md5" == "$new_md5" ] ||
21907                 error "$old_md5 != $new_md5"
21908
21909         return 0
21910 }
21911 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21912
21913 test_272f() {
21914         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21915                 skip "Need MDS version at least 2.12.55"
21916
21917         local dom=$DIR/$tdir/$tfile
21918         mkdir -p $DIR/$tdir
21919         $LFS setstripe -c 2 $dom
21920
21921         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21922                 error "failed to write data into $dom"
21923         local old_md5=$(md5sum $dom)
21924         cancel_lru_locks mdc
21925
21926         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21927                 error "failed migrating to the DOM file"
21928
21929         cancel_lru_locks mdc
21930         local new_md5=$(md5sum $dom)
21931         [ "$old_md5" != "$new_md5" ] &&
21932                 error "$old_md5 != $new_md5"
21933
21934         return 0
21935 }
21936 run_test 272f "DoM migration: OST-striped file to DOM file"
21937
21938 test_273a() {
21939         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21940                 skip "Need MDS version at least 2.11.50"
21941
21942         # Layout swap cannot be done if either file has DOM component,
21943         # this will never be supported, migration should be used instead
21944
21945         local dom=$DIR/$tdir/$tfile
21946         mkdir -p $DIR/$tdir
21947
21948         $LFS setstripe -c2 ${dom}_plain
21949         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21950         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21951                 error "can swap layout with DoM component"
21952         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21953                 error "can swap layout with DoM component"
21954
21955         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21956         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21957                 error "can swap layout with DoM component"
21958         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21959                 error "can swap layout with DoM component"
21960         return 0
21961 }
21962 run_test 273a "DoM: layout swapping should fail with DOM"
21963
21964 test_273b() {
21965         mkdir -p $DIR/$tdir
21966         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21967
21968 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21969         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21970
21971         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21972 }
21973 run_test 273b "DoM: race writeback and object destroy"
21974
21975 test_275() {
21976         remote_ost_nodsh && skip "remote OST with nodsh"
21977         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21978                 skip "Need OST version >= 2.10.57"
21979
21980         local file=$DIR/$tfile
21981         local oss
21982
21983         oss=$(comma_list $(osts_nodes))
21984
21985         dd if=/dev/urandom of=$file bs=1M count=2 ||
21986                 error "failed to create a file"
21987         cancel_lru_locks osc
21988
21989         #lock 1
21990         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21991                 error "failed to read a file"
21992
21993 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21994         $LCTL set_param fail_loc=0x8000031f
21995
21996         cancel_lru_locks osc &
21997         sleep 1
21998
21999 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22000         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22001         #IO takes another lock, but matches the PENDING one
22002         #and places it to the IO RPC
22003         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22004                 error "failed to read a file with PENDING lock"
22005 }
22006 run_test 275 "Read on a canceled duplicate lock"
22007
22008 test_276() {
22009         remote_ost_nodsh && skip "remote OST with nodsh"
22010         local pid
22011
22012         do_facet ost1 "(while true; do \
22013                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22014                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22015         pid=$!
22016
22017         for LOOP in $(seq 20); do
22018                 stop ost1
22019                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22020         done
22021         kill -9 $pid
22022         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22023                 rm $TMP/sanity_276_pid"
22024 }
22025 run_test 276 "Race between mount and obd_statfs"
22026
22027 test_277() {
22028         $LCTL set_param ldlm.namespaces.*.lru_size=0
22029         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22030         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22031                         grep ^used_mb | awk '{print $2}')
22032         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22034                 oflag=direct conv=notrunc
22035         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22036                         grep ^used_mb | awk '{print $2}')
22037         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22038 }
22039 run_test 277 "Direct IO shall drop page cache"
22040
22041 test_278() {
22042         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22043         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22044         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22045                 skip "needs the same host for mdt1 mdt2" && return
22046
22047         local pid1
22048         local pid2
22049
22050 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22051         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22052         stop mds2 &
22053         pid2=$!
22054
22055         stop mds1
22056
22057         echo "Starting MDTs"
22058         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22059         wait $pid2
22060 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22061 #will return NULL
22062         do_facet mds2 $LCTL set_param fail_loc=0
22063
22064         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22065         wait_recovery_complete mds2
22066 }
22067 run_test 278 "Race starting MDS between MDTs stop/start"
22068
22069 test_280() {
22070         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22071                 skip "Need MGS version at least 2.13.52"
22072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22073         combined_mgs_mds || skip "needs combined MGS/MDT"
22074
22075         umount_client $MOUNT
22076 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22077         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22078
22079         mount_client $MOUNT &
22080         sleep 1
22081         stop mgs || error "stop mgs failed"
22082         #for a race mgs would crash
22083         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22084         # make sure we unmount client before remounting
22085         wait
22086         umount_client $MOUNT
22087         mount_client $MOUNT || error "mount client failed"
22088 }
22089 run_test 280 "Race between MGS umount and client llog processing"
22090
22091 cleanup_test_300() {
22092         trap 0
22093         umask $SAVE_UMASK
22094 }
22095 test_striped_dir() {
22096         local mdt_index=$1
22097         local stripe_count
22098         local stripe_index
22099
22100         mkdir -p $DIR/$tdir
22101
22102         SAVE_UMASK=$(umask)
22103         trap cleanup_test_300 RETURN EXIT
22104
22105         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22106                                                 $DIR/$tdir/striped_dir ||
22107                 error "set striped dir error"
22108
22109         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22110         [ "$mode" = "755" ] || error "expect 755 got $mode"
22111
22112         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22113                 error "getdirstripe failed"
22114         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22115         if [ "$stripe_count" != "2" ]; then
22116                 error "1:stripe_count is $stripe_count, expect 2"
22117         fi
22118         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22119         if [ "$stripe_count" != "2" ]; then
22120                 error "2:stripe_count is $stripe_count, expect 2"
22121         fi
22122
22123         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22124         if [ "$stripe_index" != "$mdt_index" ]; then
22125                 error "stripe_index is $stripe_index, expect $mdt_index"
22126         fi
22127
22128         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22129                 error "nlink error after create striped dir"
22130
22131         mkdir $DIR/$tdir/striped_dir/a
22132         mkdir $DIR/$tdir/striped_dir/b
22133
22134         stat $DIR/$tdir/striped_dir/a ||
22135                 error "create dir under striped dir failed"
22136         stat $DIR/$tdir/striped_dir/b ||
22137                 error "create dir under striped dir failed"
22138
22139         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22140                 error "nlink error after mkdir"
22141
22142         rmdir $DIR/$tdir/striped_dir/a
22143         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22144                 error "nlink error after rmdir"
22145
22146         rmdir $DIR/$tdir/striped_dir/b
22147         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22148                 error "nlink error after rmdir"
22149
22150         chattr +i $DIR/$tdir/striped_dir
22151         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22152                 error "immutable flags not working under striped dir!"
22153         chattr -i $DIR/$tdir/striped_dir
22154
22155         rmdir $DIR/$tdir/striped_dir ||
22156                 error "rmdir striped dir error"
22157
22158         cleanup_test_300
22159
22160         true
22161 }
22162
22163 test_300a() {
22164         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22165                 skip "skipped for lustre < 2.7.0"
22166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22168
22169         test_striped_dir 0 || error "failed on striped dir on MDT0"
22170         test_striped_dir 1 || error "failed on striped dir on MDT0"
22171 }
22172 run_test 300a "basic striped dir sanity test"
22173
22174 test_300b() {
22175         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22176                 skip "skipped for lustre < 2.7.0"
22177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22178         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22179
22180         local i
22181         local mtime1
22182         local mtime2
22183         local mtime3
22184
22185         test_mkdir $DIR/$tdir || error "mkdir fail"
22186         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22187                 error "set striped dir error"
22188         for i in {0..9}; do
22189                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22190                 sleep 1
22191                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22192                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22193                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22194                 sleep 1
22195                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22196                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22197                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22198         done
22199         true
22200 }
22201 run_test 300b "check ctime/mtime for striped dir"
22202
22203 test_300c() {
22204         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22205                 skip "skipped for lustre < 2.7.0"
22206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22207         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22208
22209         local file_count
22210
22211         mkdir -p $DIR/$tdir
22212         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22213                 error "set striped dir error"
22214
22215         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22216                 error "chown striped dir failed"
22217
22218         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22219                 error "create 5k files failed"
22220
22221         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22222
22223         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22224
22225         rm -rf $DIR/$tdir
22226 }
22227 run_test 300c "chown && check ls under striped directory"
22228
22229 test_300d() {
22230         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22231                 skip "skipped for lustre < 2.7.0"
22232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22234
22235         local stripe_count
22236         local file
22237
22238         mkdir -p $DIR/$tdir
22239         $LFS setstripe -c 2 $DIR/$tdir
22240
22241         #local striped directory
22242         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22243                 error "set striped dir error"
22244         #look at the directories for debug purposes
22245         ls -l $DIR/$tdir
22246         $LFS getdirstripe $DIR/$tdir
22247         ls -l $DIR/$tdir/striped_dir
22248         $LFS getdirstripe $DIR/$tdir/striped_dir
22249         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22250                 error "create 10 files failed"
22251
22252         #remote striped directory
22253         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22254                 error "set striped dir error"
22255         #look at the directories for debug purposes
22256         ls -l $DIR/$tdir
22257         $LFS getdirstripe $DIR/$tdir
22258         ls -l $DIR/$tdir/remote_striped_dir
22259         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22260         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22261                 error "create 10 files failed"
22262
22263         for file in $(find $DIR/$tdir); do
22264                 stripe_count=$($LFS getstripe -c $file)
22265                 [ $stripe_count -eq 2 ] ||
22266                         error "wrong stripe $stripe_count for $file"
22267         done
22268
22269         rm -rf $DIR/$tdir
22270 }
22271 run_test 300d "check default stripe under striped directory"
22272
22273 test_300e() {
22274         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22275                 skip "Need MDS version at least 2.7.55"
22276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22277         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22278
22279         local stripe_count
22280         local file
22281
22282         mkdir -p $DIR/$tdir
22283
22284         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22285                 error "set striped dir error"
22286
22287         touch $DIR/$tdir/striped_dir/a
22288         touch $DIR/$tdir/striped_dir/b
22289         touch $DIR/$tdir/striped_dir/c
22290
22291         mkdir $DIR/$tdir/striped_dir/dir_a
22292         mkdir $DIR/$tdir/striped_dir/dir_b
22293         mkdir $DIR/$tdir/striped_dir/dir_c
22294
22295         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22296                 error "set striped adir under striped dir error"
22297
22298         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22299                 error "set striped bdir under striped dir error"
22300
22301         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22302                 error "set striped cdir under striped dir error"
22303
22304         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22305                 error "rename dir under striped dir fails"
22306
22307         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22308                 error "rename dir under different stripes fails"
22309
22310         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22311                 error "rename file under striped dir should succeed"
22312
22313         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22314                 error "rename dir under striped dir should succeed"
22315
22316         rm -rf $DIR/$tdir
22317 }
22318 run_test 300e "check rename under striped directory"
22319
22320 test_300f() {
22321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22323         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22324                 skip "Need MDS version at least 2.7.55"
22325
22326         local stripe_count
22327         local file
22328
22329         rm -rf $DIR/$tdir
22330         mkdir -p $DIR/$tdir
22331
22332         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22333                 error "set striped dir error"
22334
22335         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22336                 error "set striped dir error"
22337
22338         touch $DIR/$tdir/striped_dir/a
22339         mkdir $DIR/$tdir/striped_dir/dir_a
22340         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22341                 error "create striped dir under striped dir fails"
22342
22343         touch $DIR/$tdir/striped_dir1/b
22344         mkdir $DIR/$tdir/striped_dir1/dir_b
22345         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22346                 error "create striped dir under striped dir fails"
22347
22348         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22349                 error "rename dir under different striped dir should fail"
22350
22351         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22352                 error "rename striped dir under diff striped dir should fail"
22353
22354         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22355                 error "rename file under diff striped dirs fails"
22356
22357         rm -rf $DIR/$tdir
22358 }
22359 run_test 300f "check rename cross striped directory"
22360
22361 test_300_check_default_striped_dir()
22362 {
22363         local dirname=$1
22364         local default_count=$2
22365         local default_index=$3
22366         local stripe_count
22367         local stripe_index
22368         local dir_stripe_index
22369         local dir
22370
22371         echo "checking $dirname $default_count $default_index"
22372         $LFS setdirstripe -D -c $default_count -i $default_index \
22373                                 -H all_char $DIR/$tdir/$dirname ||
22374                 error "set default stripe on striped dir error"
22375         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22376         [ $stripe_count -eq $default_count ] ||
22377                 error "expect $default_count get $stripe_count for $dirname"
22378
22379         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22380         [ $stripe_index -eq $default_index ] ||
22381                 error "expect $default_index get $stripe_index for $dirname"
22382
22383         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22384                                                 error "create dirs failed"
22385
22386         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22387         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22388         for dir in $(find $DIR/$tdir/$dirname/*); do
22389                 stripe_count=$($LFS getdirstripe -c $dir)
22390                 (( $stripe_count == $default_count )) ||
22391                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22392                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22393                 error "stripe count $default_count != $stripe_count for $dir"
22394
22395                 stripe_index=$($LFS getdirstripe -i $dir)
22396                 [ $default_index -eq -1 ] ||
22397                         [ $stripe_index -eq $default_index ] ||
22398                         error "$stripe_index != $default_index for $dir"
22399
22400                 #check default stripe
22401                 stripe_count=$($LFS getdirstripe -D -c $dir)
22402                 [ $stripe_count -eq $default_count ] ||
22403                 error "default count $default_count != $stripe_count for $dir"
22404
22405                 stripe_index=$($LFS getdirstripe -D -i $dir)
22406                 [ $stripe_index -eq $default_index ] ||
22407                 error "default index $default_index != $stripe_index for $dir"
22408         done
22409         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22410 }
22411
22412 test_300g() {
22413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22415                 skip "Need MDS version at least 2.7.55"
22416
22417         local dir
22418         local stripe_count
22419         local stripe_index
22420
22421         mkdir $DIR/$tdir
22422         mkdir $DIR/$tdir/normal_dir
22423
22424         #Checking when client cache stripe index
22425         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22426         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22427                 error "create striped_dir failed"
22428
22429         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22430                 error "create dir0 fails"
22431         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22432         [ $stripe_index -eq 0 ] ||
22433                 error "dir0 expect index 0 got $stripe_index"
22434
22435         mkdir $DIR/$tdir/striped_dir/dir1 ||
22436                 error "create dir1 fails"
22437         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22438         [ $stripe_index -eq 1 ] ||
22439                 error "dir1 expect index 1 got $stripe_index"
22440
22441         #check default stripe count/stripe index
22442         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22443         test_300_check_default_striped_dir normal_dir 1 0
22444         test_300_check_default_striped_dir normal_dir -1 1
22445         test_300_check_default_striped_dir normal_dir 2 -1
22446
22447         #delete default stripe information
22448         echo "delete default stripeEA"
22449         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22450                 error "set default stripe on striped dir error"
22451
22452         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22453         for dir in $(find $DIR/$tdir/normal_dir/*); do
22454                 stripe_count=$($LFS getdirstripe -c $dir)
22455                 [ $stripe_count -eq 0 ] ||
22456                         error "expect 1 get $stripe_count for $dir"
22457                 stripe_index=$($LFS getdirstripe -i $dir)
22458                 [ $stripe_index -eq 0 ] ||
22459                         error "expect 0 get $stripe_index for $dir"
22460         done
22461 }
22462 run_test 300g "check default striped directory for normal directory"
22463
22464 test_300h() {
22465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22466         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22467                 skip "Need MDS version at least 2.7.55"
22468
22469         local dir
22470         local stripe_count
22471
22472         mkdir $DIR/$tdir
22473         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22474                 error "set striped dir error"
22475
22476         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22477         test_300_check_default_striped_dir striped_dir 1 0
22478         test_300_check_default_striped_dir striped_dir -1 1
22479         test_300_check_default_striped_dir striped_dir 2 -1
22480
22481         #delete default stripe information
22482         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22483                 error "set default stripe on striped dir error"
22484
22485         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22486         for dir in $(find $DIR/$tdir/striped_dir/*); do
22487                 stripe_count=$($LFS getdirstripe -c $dir)
22488                 [ $stripe_count -eq 0 ] ||
22489                         error "expect 1 get $stripe_count for $dir"
22490         done
22491 }
22492 run_test 300h "check default striped directory for striped directory"
22493
22494 test_300i() {
22495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22498                 skip "Need MDS version at least 2.7.55"
22499
22500         local stripe_count
22501         local file
22502
22503         mkdir $DIR/$tdir
22504
22505         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22506                 error "set striped dir error"
22507
22508         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22509                 error "create files under striped dir failed"
22510
22511         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22512                 error "set striped hashdir error"
22513
22514         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22515                 error "create dir0 under hash dir failed"
22516         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22517                 error "create dir1 under hash dir failed"
22518         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22519                 error "create dir2 under hash dir failed"
22520
22521         # unfortunately, we need to umount to clear dir layout cache for now
22522         # once we fully implement dir layout, we can drop this
22523         umount_client $MOUNT || error "umount failed"
22524         mount_client $MOUNT || error "mount failed"
22525
22526         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22527         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22528         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22529
22530         #set the stripe to be unknown hash type
22531         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22532         $LCTL set_param fail_loc=0x1901
22533         for ((i = 0; i < 10; i++)); do
22534                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22535                         error "stat f-$i failed"
22536                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22537         done
22538
22539         touch $DIR/$tdir/striped_dir/f0 &&
22540                 error "create under striped dir with unknown hash should fail"
22541
22542         $LCTL set_param fail_loc=0
22543
22544         umount_client $MOUNT || error "umount failed"
22545         mount_client $MOUNT || error "mount failed"
22546
22547         return 0
22548 }
22549 run_test 300i "client handle unknown hash type striped directory"
22550
22551 test_300j() {
22552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22554         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22555                 skip "Need MDS version at least 2.7.55"
22556
22557         local stripe_count
22558         local file
22559
22560         mkdir $DIR/$tdir
22561
22562         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22563         $LCTL set_param fail_loc=0x1702
22564         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22565                 error "set striped dir error"
22566
22567         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22568                 error "create files under striped dir failed"
22569
22570         $LCTL set_param fail_loc=0
22571
22572         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22573
22574         return 0
22575 }
22576 run_test 300j "test large update record"
22577
22578 test_300k() {
22579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22581         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22582                 skip "Need MDS version at least 2.7.55"
22583
22584         # this test needs a huge transaction
22585         local kb
22586         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22587              osd*.$FSNAME-MDT0000.kbytestotal")
22588         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22589
22590         local stripe_count
22591         local file
22592
22593         mkdir $DIR/$tdir
22594
22595         #define OBD_FAIL_LARGE_STRIPE   0x1703
22596         $LCTL set_param fail_loc=0x1703
22597         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22598                 error "set striped dir error"
22599         $LCTL set_param fail_loc=0
22600
22601         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22602                 error "getstripeddir fails"
22603         rm -rf $DIR/$tdir/striped_dir ||
22604                 error "unlink striped dir fails"
22605
22606         return 0
22607 }
22608 run_test 300k "test large striped directory"
22609
22610 test_300l() {
22611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22613         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22614                 skip "Need MDS version at least 2.7.55"
22615
22616         local stripe_index
22617
22618         test_mkdir -p $DIR/$tdir/striped_dir
22619         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22620                         error "chown $RUNAS_ID failed"
22621         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22622                 error "set default striped dir failed"
22623
22624         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22625         $LCTL set_param fail_loc=0x80000158
22626         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22627
22628         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22629         [ $stripe_index -eq 1 ] ||
22630                 error "expect 1 get $stripe_index for $dir"
22631 }
22632 run_test 300l "non-root user to create dir under striped dir with stale layout"
22633
22634 test_300m() {
22635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22636         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22637         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22638                 skip "Need MDS version at least 2.7.55"
22639
22640         mkdir -p $DIR/$tdir/striped_dir
22641         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22642                 error "set default stripes dir error"
22643
22644         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22645
22646         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22647         [ $stripe_count -eq 0 ] ||
22648                         error "expect 0 get $stripe_count for a"
22649
22650         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22651                 error "set default stripes dir error"
22652
22653         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22654
22655         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22656         [ $stripe_count -eq 0 ] ||
22657                         error "expect 0 get $stripe_count for b"
22658
22659         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22660                 error "set default stripes dir error"
22661
22662         mkdir $DIR/$tdir/striped_dir/c &&
22663                 error "default stripe_index is invalid, mkdir c should fails"
22664
22665         rm -rf $DIR/$tdir || error "rmdir fails"
22666 }
22667 run_test 300m "setstriped directory on single MDT FS"
22668
22669 cleanup_300n() {
22670         local list=$(comma_list $(mdts_nodes))
22671
22672         trap 0
22673         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22674 }
22675
22676 test_300n() {
22677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22679         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22680                 skip "Need MDS version at least 2.7.55"
22681         remote_mds_nodsh && skip "remote MDS with nodsh"
22682
22683         local stripe_index
22684         local list=$(comma_list $(mdts_nodes))
22685
22686         trap cleanup_300n RETURN EXIT
22687         mkdir -p $DIR/$tdir
22688         chmod 777 $DIR/$tdir
22689         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22690                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22691                 error "create striped dir succeeds with gid=0"
22692
22693         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22694         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22695                 error "create striped dir fails with gid=-1"
22696
22697         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22698         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22699                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22700                 error "set default striped dir succeeds with gid=0"
22701
22702
22703         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22704         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22705                 error "set default striped dir fails with gid=-1"
22706
22707
22708         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22709         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22710                                         error "create test_dir fails"
22711         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22712                                         error "create test_dir1 fails"
22713         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22714                                         error "create test_dir2 fails"
22715         cleanup_300n
22716 }
22717 run_test 300n "non-root user to create dir under striped dir with default EA"
22718
22719 test_300o() {
22720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22721         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22722         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22723                 skip "Need MDS version at least 2.7.55"
22724
22725         local numfree1
22726         local numfree2
22727
22728         mkdir -p $DIR/$tdir
22729
22730         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22731         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22732         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22733                 skip "not enough free inodes $numfree1 $numfree2"
22734         fi
22735
22736         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22737         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22738         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22739                 skip "not enough free space $numfree1 $numfree2"
22740         fi
22741
22742         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22743                 error "setdirstripe fails"
22744
22745         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22746                 error "create dirs fails"
22747
22748         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22749         ls $DIR/$tdir/striped_dir > /dev/null ||
22750                 error "ls striped dir fails"
22751         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22752                 error "unlink big striped dir fails"
22753 }
22754 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22755
22756 test_300p() {
22757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22759         remote_mds_nodsh && skip "remote MDS with nodsh"
22760
22761         mkdir -p $DIR/$tdir
22762
22763         #define OBD_FAIL_OUT_ENOSPC     0x1704
22764         do_facet mds2 lctl set_param fail_loc=0x80001704
22765         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22766                  && error "create striped directory should fail"
22767
22768         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22769
22770         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22771         true
22772 }
22773 run_test 300p "create striped directory without space"
22774
22775 test_300q() {
22776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22777         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22778
22779         local fd=$(free_fd)
22780         local cmd="exec $fd<$tdir"
22781         cd $DIR
22782         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22783         eval $cmd
22784         cmd="exec $fd<&-"
22785         trap "eval $cmd" EXIT
22786         cd $tdir || error "cd $tdir fails"
22787         rmdir  ../$tdir || error "rmdir $tdir fails"
22788         mkdir local_dir && error "create dir succeeds"
22789         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22790         eval $cmd
22791         return 0
22792 }
22793 run_test 300q "create remote directory under orphan directory"
22794
22795 test_300r() {
22796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22797                 skip "Need MDS version at least 2.7.55" && return
22798         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22799
22800         mkdir $DIR/$tdir
22801
22802         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22803                 error "set striped dir error"
22804
22805         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22806                 error "getstripeddir fails"
22807
22808         local stripe_count
22809         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22810                       awk '/lmv_stripe_count:/ { print $2 }')
22811
22812         [ $MDSCOUNT -ne $stripe_count ] &&
22813                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22814
22815         rm -rf $DIR/$tdir/striped_dir ||
22816                 error "unlink striped dir fails"
22817 }
22818 run_test 300r "test -1 striped directory"
22819
22820 test_300s_helper() {
22821         local count=$1
22822
22823         local stripe_dir=$DIR/$tdir/striped_dir.$count
22824
22825         $LFS mkdir -c $count $stripe_dir ||
22826                 error "lfs mkdir -c error"
22827
22828         $LFS getdirstripe $stripe_dir ||
22829                 error "lfs getdirstripe fails"
22830
22831         local stripe_count
22832         stripe_count=$($LFS getdirstripe $stripe_dir |
22833                       awk '/lmv_stripe_count:/ { print $2 }')
22834
22835         [ $count -ne $stripe_count ] &&
22836                 error_noexit "bad stripe count $stripe_count expected $count"
22837
22838         local dupe_stripes
22839         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22840                 awk '/0x/ {count[$1] += 1}; END {
22841                         for (idx in count) {
22842                                 if (count[idx]>1) {
22843                                         print "index " idx " count " count[idx]
22844                                 }
22845                         }
22846                 }')
22847
22848         if [[ -n "$dupe_stripes" ]] ; then
22849                 lfs getdirstripe $stripe_dir
22850                 error_noexit "Dupe MDT above: $dupe_stripes "
22851         fi
22852
22853         rm -rf $stripe_dir ||
22854                 error_noexit "unlink $stripe_dir fails"
22855 }
22856
22857 test_300s() {
22858         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22859                 skip "Need MDS version at least 2.7.55" && return
22860         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22861
22862         mkdir $DIR/$tdir
22863         for count in $(seq 2 $MDSCOUNT); do
22864                 test_300s_helper $count
22865         done
22866 }
22867 run_test 300s "test lfs mkdir -c without -i"
22868
22869
22870 prepare_remote_file() {
22871         mkdir $DIR/$tdir/src_dir ||
22872                 error "create remote source failed"
22873
22874         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22875                  error "cp to remote source failed"
22876         touch $DIR/$tdir/src_dir/a
22877
22878         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22879                 error "create remote target dir failed"
22880
22881         touch $DIR/$tdir/tgt_dir/b
22882
22883         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22884                 error "rename dir cross MDT failed!"
22885
22886         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22887                 error "src_child still exists after rename"
22888
22889         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22890                 error "missing file(a) after rename"
22891
22892         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22893                 error "diff after rename"
22894 }
22895
22896 test_310a() {
22897         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22899
22900         local remote_file=$DIR/$tdir/tgt_dir/b
22901
22902         mkdir -p $DIR/$tdir
22903
22904         prepare_remote_file || error "prepare remote file failed"
22905
22906         #open-unlink file
22907         $OPENUNLINK $remote_file $remote_file ||
22908                 error "openunlink $remote_file failed"
22909         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22910 }
22911 run_test 310a "open unlink remote file"
22912
22913 test_310b() {
22914         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22916
22917         local remote_file=$DIR/$tdir/tgt_dir/b
22918
22919         mkdir -p $DIR/$tdir
22920
22921         prepare_remote_file || error "prepare remote file failed"
22922
22923         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22924         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22925         $CHECKSTAT -t file $remote_file || error "check file failed"
22926 }
22927 run_test 310b "unlink remote file with multiple links while open"
22928
22929 test_310c() {
22930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22931         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22932
22933         local remote_file=$DIR/$tdir/tgt_dir/b
22934
22935         mkdir -p $DIR/$tdir
22936
22937         prepare_remote_file || error "prepare remote file failed"
22938
22939         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22940         multiop_bg_pause $remote_file O_uc ||
22941                         error "mulitop failed for remote file"
22942         MULTIPID=$!
22943         $MULTIOP $DIR/$tfile Ouc
22944         kill -USR1 $MULTIPID
22945         wait $MULTIPID
22946 }
22947 run_test 310c "open-unlink remote file with multiple links"
22948
22949 #LU-4825
22950 test_311() {
22951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22952         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22953         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22954                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22955         remote_mds_nodsh && skip "remote MDS with nodsh"
22956
22957         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22958         local mdts=$(comma_list $(mdts_nodes))
22959
22960         mkdir -p $DIR/$tdir
22961         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22962         createmany -o $DIR/$tdir/$tfile. 1000
22963
22964         # statfs data is not real time, let's just calculate it
22965         old_iused=$((old_iused + 1000))
22966
22967         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22968                         osp.*OST0000*MDT0000.create_count")
22969         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22970                                 osp.*OST0000*MDT0000.max_create_count")
22971         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22972
22973         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22974         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22975         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22976
22977         unlinkmany $DIR/$tdir/$tfile. 1000
22978
22979         do_nodes $mdts "$LCTL set_param -n \
22980                         osp.*OST0000*.max_create_count=$max_count"
22981         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22982                 do_nodes $mdts "$LCTL set_param -n \
22983                                 osp.*OST0000*.create_count=$count"
22984         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22985                         grep "=0" && error "create_count is zero"
22986
22987         local new_iused
22988         for i in $(seq 120); do
22989                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22990                 # system may be too busy to destroy all objs in time, use
22991                 # a somewhat small value to not fail autotest
22992                 [ $((old_iused - new_iused)) -gt 400 ] && break
22993                 sleep 1
22994         done
22995
22996         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22997         [ $((old_iused - new_iused)) -gt 400 ] ||
22998                 error "objs not destroyed after unlink"
22999 }
23000 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23001
23002 zfs_oid_to_objid()
23003 {
23004         local ost=$1
23005         local objid=$2
23006
23007         local vdevdir=$(dirname $(facet_vdevice $ost))
23008         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23009         local zfs_zapid=$(do_facet $ost $cmd |
23010                           grep -w "/O/0/d$((objid%32))" -C 5 |
23011                           awk '/Object/{getline; print $1}')
23012         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23013                           awk "/$objid = /"'{printf $3}')
23014
23015         echo $zfs_objid
23016 }
23017
23018 zfs_object_blksz() {
23019         local ost=$1
23020         local objid=$2
23021
23022         local vdevdir=$(dirname $(facet_vdevice $ost))
23023         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23024         local blksz=$(do_facet $ost $cmd $objid |
23025                       awk '/dblk/{getline; printf $4}')
23026
23027         case "${blksz: -1}" in
23028                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23029                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23030                 *) ;;
23031         esac
23032
23033         echo $blksz
23034 }
23035
23036 test_312() { # LU-4856
23037         remote_ost_nodsh && skip "remote OST with nodsh"
23038         [ "$ost1_FSTYPE" = "zfs" ] ||
23039                 skip_env "the test only applies to zfs"
23040
23041         local max_blksz=$(do_facet ost1 \
23042                           $ZFS get -p recordsize $(facet_device ost1) |
23043                           awk '!/VALUE/{print $3}')
23044
23045         # to make life a little bit easier
23046         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23047         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23048
23049         local tf=$DIR/$tdir/$tfile
23050         touch $tf
23051         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23052
23053         # Get ZFS object id
23054         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23055         # block size change by sequential overwrite
23056         local bs
23057
23058         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23059                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23060
23061                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23062                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23063         done
23064         rm -f $tf
23065
23066         # block size change by sequential append write
23067         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23068         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23069         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23070         local count
23071
23072         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23073                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23074                         oflag=sync conv=notrunc
23075
23076                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23077                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23078                         error "blksz error, actual $blksz, " \
23079                                 "expected: 2 * $count * $PAGE_SIZE"
23080         done
23081         rm -f $tf
23082
23083         # random write
23084         touch $tf
23085         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23086         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23087
23088         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23089         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23090         [ $blksz -eq $PAGE_SIZE ] ||
23091                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23092
23093         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23094         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23095         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23096
23097         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23098         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23099         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23100 }
23101 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23102
23103 test_313() {
23104         remote_ost_nodsh && skip "remote OST with nodsh"
23105
23106         local file=$DIR/$tfile
23107
23108         rm -f $file
23109         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23110
23111         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23112         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23113         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23114                 error "write should failed"
23115         do_facet ost1 "$LCTL set_param fail_loc=0"
23116         rm -f $file
23117 }
23118 run_test 313 "io should fail after last_rcvd update fail"
23119
23120 test_314() {
23121         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23122
23123         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23124         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23125         rm -f $DIR/$tfile
23126         wait_delete_completed
23127         do_facet ost1 "$LCTL set_param fail_loc=0"
23128 }
23129 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23130
23131 test_315() { # LU-618
23132         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23133
23134         local file=$DIR/$tfile
23135         rm -f $file
23136
23137         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23138                 error "multiop file write failed"
23139         $MULTIOP $file oO_RDONLY:r4063232_c &
23140         PID=$!
23141
23142         sleep 2
23143
23144         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23145         kill -USR1 $PID
23146
23147         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23148         rm -f $file
23149 }
23150 run_test 315 "read should be accounted"
23151
23152 test_316() {
23153         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23154         large_xattr_enabled || skip_env "ea_inode feature disabled"
23155
23156         rm -rf $DIR/$tdir/d
23157         mkdir -p $DIR/$tdir/d
23158         chown nobody $DIR/$tdir/d
23159         touch $DIR/$tdir/d/file
23160
23161         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23162 }
23163 run_test 316 "lfs mv"
23164
23165 test_317() {
23166         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23167                 skip "Need MDS version at least 2.11.53"
23168         if [ "$ost1_FSTYPE" == "zfs" ]; then
23169                 skip "LU-10370: no implementation for ZFS"
23170         fi
23171
23172         local trunc_sz
23173         local grant_blk_size
23174
23175         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23176                         awk '/grant_block_size:/ { print $2; exit; }')
23177         #
23178         # Create File of size 5M. Truncate it to below size's and verify
23179         # blocks count.
23180         #
23181         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23182                 error "Create file $DIR/$tfile failed"
23183         stack_trap "rm -f $DIR/$tfile" EXIT
23184
23185         for trunc_sz in 2097152 4097 4000 509 0; do
23186                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23187                         error "truncate $tfile to $trunc_sz failed"
23188                 local sz=$(stat --format=%s $DIR/$tfile)
23189                 local blk=$(stat --format=%b $DIR/$tfile)
23190                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23191                                      grant_blk_size) * 8))
23192
23193                 if [[ $blk -ne $trunc_blk ]]; then
23194                         $(which stat) $DIR/$tfile
23195                         error "Expected Block $trunc_blk got $blk for $tfile"
23196                 fi
23197
23198                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23199                         error "Expected Size $trunc_sz got $sz for $tfile"
23200         done
23201
23202         #
23203         # sparse file test
23204         # Create file with a hole and write actual two blocks. Block count
23205         # must be 16.
23206         #
23207         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23208                 conv=fsync || error "Create file : $DIR/$tfile"
23209
23210         # Calculate the final truncate size.
23211         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23212
23213         #
23214         # truncate to size $trunc_sz bytes. Strip the last block
23215         # The block count must drop to 8
23216         #
23217         $TRUNCATE $DIR/$tfile $trunc_sz ||
23218                 error "truncate $tfile to $trunc_sz failed"
23219
23220         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23221         sz=$(stat --format=%s $DIR/$tfile)
23222         blk=$(stat --format=%b $DIR/$tfile)
23223
23224         if [[ $blk -ne $trunc_bsz ]]; then
23225                 $(which stat) $DIR/$tfile
23226                 error "Expected Block $trunc_bsz got $blk for $tfile"
23227         fi
23228
23229         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23230                 error "Expected Size $trunc_sz got $sz for $tfile"
23231 }
23232 run_test 317 "Verify blocks get correctly update after truncate"
23233
23234 test_318() {
23235         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23236         local old_max_active=$($LCTL get_param -n \
23237                             ${llite_name}.max_read_ahead_async_active \
23238                             2>/dev/null)
23239
23240         $LCTL set_param llite.*.max_read_ahead_async_active=256
23241         local max_active=$($LCTL get_param -n \
23242                            ${llite_name}.max_read_ahead_async_active \
23243                            2>/dev/null)
23244         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23245
23246         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23247                 error "set max_read_ahead_async_active should succeed"
23248
23249         $LCTL set_param llite.*.max_read_ahead_async_active=512
23250         max_active=$($LCTL get_param -n \
23251                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23252         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23253
23254         # restore @max_active
23255         [ $old_max_active -ne 0 ] && $LCTL set_param \
23256                 llite.*.max_read_ahead_async_active=$old_max_active
23257
23258         local old_threshold=$($LCTL get_param -n \
23259                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23260         local max_per_file_mb=$($LCTL get_param -n \
23261                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23262
23263         local invalid=$(($max_per_file_mb + 1))
23264         $LCTL set_param \
23265                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23266                         && error "set $invalid should fail"
23267
23268         local valid=$(($invalid - 1))
23269         $LCTL set_param \
23270                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23271                         error "set $valid should succeed"
23272         local threshold=$($LCTL get_param -n \
23273                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23274         [ $threshold -eq $valid ] || error \
23275                 "expect threshold $valid got $threshold"
23276         $LCTL set_param \
23277                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23278 }
23279 run_test 318 "Verify async readahead tunables"
23280
23281 test_319() {
23282         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23283
23284         local before=$(date +%s)
23285         local evict
23286         local mdir=$DIR/$tdir
23287         local file=$mdir/xxx
23288
23289         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23290         touch $file
23291
23292 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23293         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23294         $LFS mv -m1 $file &
23295
23296         sleep 1
23297         dd if=$file of=/dev/null
23298         wait
23299         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23300           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23301
23302         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23303 }
23304 run_test 319 "lost lease lock on migrate error"
23305
23306 test_398a() { # LU-4198
23307         local ost1_imp=$(get_osc_import_name client ost1)
23308         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23309                          cut -d'.' -f2)
23310
23311         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23312         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23313
23314         # request a new lock on client
23315         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23316
23317         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23318         local lock_count=$($LCTL get_param -n \
23319                            ldlm.namespaces.$imp_name.lru_size)
23320         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23321
23322         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23323
23324         # no lock cached, should use lockless IO and not enqueue new lock
23325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23326         lock_count=$($LCTL get_param -n \
23327                      ldlm.namespaces.$imp_name.lru_size)
23328         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23329 }
23330 run_test 398a "direct IO should cancel lock otherwise lockless"
23331
23332 test_398b() { # LU-4198
23333         which fio || skip_env "no fio installed"
23334         $LFS setstripe -c -1 $DIR/$tfile
23335
23336         local size=12
23337         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23338
23339         local njobs=4
23340         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23341         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23342                 --numjobs=$njobs --fallocate=none \
23343                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23344                 --filename=$DIR/$tfile &
23345         bg_pid=$!
23346
23347         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23348         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23349                 --numjobs=$njobs --fallocate=none \
23350                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23351                 --filename=$DIR/$tfile || true
23352         wait $bg_pid
23353
23354         rm -f $DIR/$tfile
23355 }
23356 run_test 398b "DIO and buffer IO race"
23357
23358 test_398c() { # LU-4198
23359         local ost1_imp=$(get_osc_import_name client ost1)
23360         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23361                          cut -d'.' -f2)
23362
23363         which fio || skip_env "no fio installed"
23364
23365         saved_debug=$($LCTL get_param -n debug)
23366         $LCTL set_param debug=0
23367
23368         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23369         ((size /= 1024)) # by megabytes
23370         ((size /= 2)) # write half of the OST at most
23371         [ $size -gt 40 ] && size=40 #reduce test time anyway
23372
23373         $LFS setstripe -c 1 $DIR/$tfile
23374
23375         # it seems like ldiskfs reserves more space than necessary if the
23376         # writing blocks are not mapped, so it extends the file firstly
23377         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23378         cancel_lru_locks osc
23379
23380         # clear and verify rpc_stats later
23381         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23382
23383         local njobs=4
23384         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23385         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23386                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23387                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23388                 --filename=$DIR/$tfile
23389         [ $? -eq 0 ] || error "fio write error"
23390
23391         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23392                 error "Locks were requested while doing AIO"
23393
23394         # get the percentage of 1-page I/O
23395         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23396                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23397                 awk '{print $7}')
23398         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23399
23400         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23401         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23402                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23403                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23404                 --filename=$DIR/$tfile
23405         [ $? -eq 0 ] || error "fio mixed read write error"
23406
23407         echo "AIO with large block size ${size}M"
23408         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23409                 --numjobs=1 --fallocate=none --ioengine=libaio \
23410                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23411                 --filename=$DIR/$tfile
23412         [ $? -eq 0 ] || error "fio large block size failed"
23413
23414         rm -f $DIR/$tfile
23415         $LCTL set_param debug="$saved_debug"
23416 }
23417 run_test 398c "run fio to test AIO"
23418
23419 test_398d() { #  LU-13846
23420         which aiocp || skip_env "no aiocp installed"
23421         local aio_file=$DIR/$tfile.aio
23422
23423         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23424
23425         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23426         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23427         stack_trap "rm -f $DIR/$tfile $aio_file"
23428
23429         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23430
23431         # make sure we don't crash and fail properly
23432         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23433                 error "aio not aligned with PAGE SIZE should fail"
23434
23435         rm -f $DIR/$tfile $aio_file
23436 }
23437 run_test 398d "run aiocp to verify block size > stripe size"
23438
23439 test_398e() {
23440         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23441         touch $DIR/$tfile.new
23442         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23443 }
23444 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23445
23446 test_398f() { #  LU-14687
23447         which aiocp || skip_env "no aiocp installed"
23448         local aio_file=$DIR/$tfile.aio
23449
23450         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23451
23452         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23453         stack_trap "rm -f $DIR/$tfile $aio_file"
23454
23455         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23456         $LCTL set_param fail_loc=0x1418
23457         # make sure we don't crash and fail properly
23458         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23459                 error "aio with page allocation failure succeeded"
23460         $LCTL set_param fail_loc=0
23461         diff $DIR/$tfile $aio_file
23462         [[ $? != 0 ]] || error "no diff after failed aiocp"
23463 }
23464 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23465
23466 test_fake_rw() {
23467         local read_write=$1
23468         if [ "$read_write" = "write" ]; then
23469                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23470         elif [ "$read_write" = "read" ]; then
23471                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23472         else
23473                 error "argument error"
23474         fi
23475
23476         # turn off debug for performance testing
23477         local saved_debug=$($LCTL get_param -n debug)
23478         $LCTL set_param debug=0
23479
23480         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23481
23482         # get ost1 size - $FSNAME-OST0000
23483         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23484         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23485         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23486
23487         if [ "$read_write" = "read" ]; then
23488                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23489         fi
23490
23491         local start_time=$(date +%s.%N)
23492         $dd_cmd bs=1M count=$blocks oflag=sync ||
23493                 error "real dd $read_write error"
23494         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23495
23496         if [ "$read_write" = "write" ]; then
23497                 rm -f $DIR/$tfile
23498         fi
23499
23500         # define OBD_FAIL_OST_FAKE_RW           0x238
23501         do_facet ost1 $LCTL set_param fail_loc=0x238
23502
23503         local start_time=$(date +%s.%N)
23504         $dd_cmd bs=1M count=$blocks oflag=sync ||
23505                 error "fake dd $read_write error"
23506         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23507
23508         if [ "$read_write" = "write" ]; then
23509                 # verify file size
23510                 cancel_lru_locks osc
23511                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23512                         error "$tfile size not $blocks MB"
23513         fi
23514         do_facet ost1 $LCTL set_param fail_loc=0
23515
23516         echo "fake $read_write $duration_fake vs. normal $read_write" \
23517                 "$duration in seconds"
23518         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23519                 error_not_in_vm "fake write is slower"
23520
23521         $LCTL set_param -n debug="$saved_debug"
23522         rm -f $DIR/$tfile
23523 }
23524 test_399a() { # LU-7655 for OST fake write
23525         remote_ost_nodsh && skip "remote OST with nodsh"
23526
23527         test_fake_rw write
23528 }
23529 run_test 399a "fake write should not be slower than normal write"
23530
23531 test_399b() { # LU-8726 for OST fake read
23532         remote_ost_nodsh && skip "remote OST with nodsh"
23533         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23534                 skip_env "ldiskfs only test"
23535         fi
23536
23537         test_fake_rw read
23538 }
23539 run_test 399b "fake read should not be slower than normal read"
23540
23541 test_400a() { # LU-1606, was conf-sanity test_74
23542         if ! which $CC > /dev/null 2>&1; then
23543                 skip_env "$CC is not installed"
23544         fi
23545
23546         local extra_flags=''
23547         local out=$TMP/$tfile
23548         local prefix=/usr/include/lustre
23549         local prog
23550
23551         # Oleg removes c files in his test rig so test if any c files exist
23552         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23553                 skip_env "Needed c test files are missing"
23554
23555         if ! [[ -d $prefix ]]; then
23556                 # Assume we're running in tree and fixup the include path.
23557                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23558                 extra_flags+=" -L$LUSTRE/utils/.lib"
23559         fi
23560
23561         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23562                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23563                         error "client api broken"
23564         done
23565         rm -f $out
23566 }
23567 run_test 400a "Lustre client api program can compile and link"
23568
23569 test_400b() { # LU-1606, LU-5011
23570         local header
23571         local out=$TMP/$tfile
23572         local prefix=/usr/include/linux/lustre
23573
23574         # We use a hard coded prefix so that this test will not fail
23575         # when run in tree. There are headers in lustre/include/lustre/
23576         # that are not packaged (like lustre_idl.h) and have more
23577         # complicated include dependencies (like config.h and lnet/types.h).
23578         # Since this test about correct packaging we just skip them when
23579         # they don't exist (see below) rather than try to fixup cppflags.
23580
23581         if ! which $CC > /dev/null 2>&1; then
23582                 skip_env "$CC is not installed"
23583         fi
23584
23585         for header in $prefix/*.h; do
23586                 if ! [[ -f "$header" ]]; then
23587                         continue
23588                 fi
23589
23590                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23591                         continue # lustre_ioctl.h is internal header
23592                 fi
23593
23594                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23595                         error "cannot compile '$header'"
23596         done
23597         rm -f $out
23598 }
23599 run_test 400b "packaged headers can be compiled"
23600
23601 test_401a() { #LU-7437
23602         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23603         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23604
23605         #count the number of parameters by "list_param -R"
23606         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23607         #count the number of parameters by listing proc files
23608         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23609         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23610         echo "proc_dirs='$proc_dirs'"
23611         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23612         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23613                       sort -u | wc -l)
23614
23615         [ $params -eq $procs ] ||
23616                 error "found $params parameters vs. $procs proc files"
23617
23618         # test the list_param -D option only returns directories
23619         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23620         #count the number of parameters by listing proc directories
23621         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23622                 sort -u | wc -l)
23623
23624         [ $params -eq $procs ] ||
23625                 error "found $params parameters vs. $procs proc files"
23626 }
23627 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23628
23629 test_401b() {
23630         # jobid_var may not allow arbitrary values, so use jobid_name
23631         # if available
23632         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23633                 local testname=jobid_name tmp='testing%p'
23634         else
23635                 local testname=jobid_var tmp=testing
23636         fi
23637
23638         local save=$($LCTL get_param -n $testname)
23639
23640         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23641                 error "no error returned when setting bad parameters"
23642
23643         local jobid_new=$($LCTL get_param -n foe $testname baz)
23644         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23645
23646         $LCTL set_param -n fog=bam $testname=$save bat=fog
23647         local jobid_old=$($LCTL get_param -n foe $testname bag)
23648         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23649 }
23650 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23651
23652 test_401c() {
23653         # jobid_var may not allow arbitrary values, so use jobid_name
23654         # if available
23655         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23656                 local testname=jobid_name
23657         else
23658                 local testname=jobid_var
23659         fi
23660
23661         local jobid_var_old=$($LCTL get_param -n $testname)
23662         local jobid_var_new
23663
23664         $LCTL set_param $testname= &&
23665                 error "no error returned for 'set_param a='"
23666
23667         jobid_var_new=$($LCTL get_param -n $testname)
23668         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23669                 error "$testname was changed by setting without value"
23670
23671         $LCTL set_param $testname &&
23672                 error "no error returned for 'set_param a'"
23673
23674         jobid_var_new=$($LCTL get_param -n $testname)
23675         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23676                 error "$testname was changed by setting without value"
23677 }
23678 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23679
23680 test_401d() {
23681         # jobid_var may not allow arbitrary values, so use jobid_name
23682         # if available
23683         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23684                 local testname=jobid_name new_value='foo=bar%p'
23685         else
23686                 local testname=jobid_var new_valuie=foo=bar
23687         fi
23688
23689         local jobid_var_old=$($LCTL get_param -n $testname)
23690         local jobid_var_new
23691
23692         $LCTL set_param $testname=$new_value ||
23693                 error "'set_param a=b' did not accept a value containing '='"
23694
23695         jobid_var_new=$($LCTL get_param -n $testname)
23696         [[ "$jobid_var_new" == "$new_value" ]] ||
23697                 error "'set_param a=b' failed on a value containing '='"
23698
23699         # Reset the $testname to test the other format
23700         $LCTL set_param $testname=$jobid_var_old
23701         jobid_var_new=$($LCTL get_param -n $testname)
23702         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23703                 error "failed to reset $testname"
23704
23705         $LCTL set_param $testname $new_value ||
23706                 error "'set_param a b' did not accept a value containing '='"
23707
23708         jobid_var_new=$($LCTL get_param -n $testname)
23709         [[ "$jobid_var_new" == "$new_value" ]] ||
23710                 error "'set_param a b' failed on a value containing '='"
23711
23712         $LCTL set_param $testname $jobid_var_old
23713         jobid_var_new=$($LCTL get_param -n $testname)
23714         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23715                 error "failed to reset $testname"
23716 }
23717 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23718
23719 test_402() {
23720         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23721         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23722                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23723         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23724                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23725                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23726         remote_mds_nodsh && skip "remote MDS with nodsh"
23727
23728         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23729 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23730         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23731         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23732                 echo "Touch failed - OK"
23733 }
23734 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23735
23736 test_403() {
23737         local file1=$DIR/$tfile.1
23738         local file2=$DIR/$tfile.2
23739         local tfile=$TMP/$tfile
23740
23741         rm -f $file1 $file2 $tfile
23742
23743         touch $file1
23744         ln $file1 $file2
23745
23746         # 30 sec OBD_TIMEOUT in ll_getattr()
23747         # right before populating st_nlink
23748         $LCTL set_param fail_loc=0x80001409
23749         stat -c %h $file1 > $tfile &
23750
23751         # create an alias, drop all locks and reclaim the dentry
23752         < $file2
23753         cancel_lru_locks mdc
23754         cancel_lru_locks osc
23755         sysctl -w vm.drop_caches=2
23756
23757         wait
23758
23759         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23760
23761         rm -f $tfile $file1 $file2
23762 }
23763 run_test 403 "i_nlink should not drop to zero due to aliasing"
23764
23765 test_404() { # LU-6601
23766         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23767                 skip "Need server version newer than 2.8.52"
23768         remote_mds_nodsh && skip "remote MDS with nodsh"
23769
23770         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23771                 awk '/osp .*-osc-MDT/ { print $4}')
23772
23773         local osp
23774         for osp in $mosps; do
23775                 echo "Deactivate: " $osp
23776                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23777                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23778                         awk -vp=$osp '$4 == p { print $2 }')
23779                 [ $stat = IN ] || {
23780                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23781                         error "deactivate error"
23782                 }
23783                 echo "Activate: " $osp
23784                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23785                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23786                         awk -vp=$osp '$4 == p { print $2 }')
23787                 [ $stat = UP ] || {
23788                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23789                         error "activate error"
23790                 }
23791         done
23792 }
23793 run_test 404 "validate manual {de}activated works properly for OSPs"
23794
23795 test_405() {
23796         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23797         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23798                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23799                         skip "Layout swap lock is not supported"
23800
23801         check_swap_layouts_support
23802         check_swap_layout_no_dom $DIR
23803
23804         test_mkdir $DIR/$tdir
23805         swap_lock_test -d $DIR/$tdir ||
23806                 error "One layout swap locked test failed"
23807 }
23808 run_test 405 "Various layout swap lock tests"
23809
23810 test_406() {
23811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23812         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23813         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23815         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23816                 skip "Need MDS version at least 2.8.50"
23817
23818         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23819         local test_pool=$TESTNAME
23820
23821         pool_add $test_pool || error "pool_add failed"
23822         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23823                 error "pool_add_targets failed"
23824
23825         save_layout_restore_at_exit $MOUNT
23826
23827         # parent set default stripe count only, child will stripe from both
23828         # parent and fs default
23829         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23830                 error "setstripe $MOUNT failed"
23831         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23832         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23833         for i in $(seq 10); do
23834                 local f=$DIR/$tdir/$tfile.$i
23835                 touch $f || error "touch failed"
23836                 local count=$($LFS getstripe -c $f)
23837                 [ $count -eq $OSTCOUNT ] ||
23838                         error "$f stripe count $count != $OSTCOUNT"
23839                 local offset=$($LFS getstripe -i $f)
23840                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23841                 local size=$($LFS getstripe -S $f)
23842                 [ $size -eq $((def_stripe_size * 2)) ] ||
23843                         error "$f stripe size $size != $((def_stripe_size * 2))"
23844                 local pool=$($LFS getstripe -p $f)
23845                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23846         done
23847
23848         # change fs default striping, delete parent default striping, now child
23849         # will stripe from new fs default striping only
23850         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23851                 error "change $MOUNT default stripe failed"
23852         $LFS setstripe -c 0 $DIR/$tdir ||
23853                 error "delete $tdir default stripe failed"
23854         for i in $(seq 11 20); do
23855                 local f=$DIR/$tdir/$tfile.$i
23856                 touch $f || error "touch $f failed"
23857                 local count=$($LFS getstripe -c $f)
23858                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23859                 local offset=$($LFS getstripe -i $f)
23860                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23861                 local size=$($LFS getstripe -S $f)
23862                 [ $size -eq $def_stripe_size ] ||
23863                         error "$f stripe size $size != $def_stripe_size"
23864                 local pool=$($LFS getstripe -p $f)
23865                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23866         done
23867
23868         unlinkmany $DIR/$tdir/$tfile. 1 20
23869
23870         local f=$DIR/$tdir/$tfile
23871         pool_remove_all_targets $test_pool $f
23872         pool_remove $test_pool $f
23873 }
23874 run_test 406 "DNE support fs default striping"
23875
23876 test_407() {
23877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23878         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23879                 skip "Need MDS version at least 2.8.55"
23880         remote_mds_nodsh && skip "remote MDS with nodsh"
23881
23882         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23883                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23884         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23885                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23886         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23887
23888         #define OBD_FAIL_DT_TXN_STOP    0x2019
23889         for idx in $(seq $MDSCOUNT); do
23890                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23891         done
23892         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23893         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23894                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23895         true
23896 }
23897 run_test 407 "transaction fail should cause operation fail"
23898
23899 test_408() {
23900         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23901
23902         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23903         lctl set_param fail_loc=0x8000040a
23904         # let ll_prepare_partial_page() fail
23905         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23906
23907         rm -f $DIR/$tfile
23908
23909         # create at least 100 unused inodes so that
23910         # shrink_icache_memory(0) should not return 0
23911         touch $DIR/$tfile-{0..100}
23912         rm -f $DIR/$tfile-{0..100}
23913         sync
23914
23915         echo 2 > /proc/sys/vm/drop_caches
23916 }
23917 run_test 408 "drop_caches should not hang due to page leaks"
23918
23919 test_409()
23920 {
23921         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23922
23923         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23924         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23925         touch $DIR/$tdir/guard || error "(2) Fail to create"
23926
23927         local PREFIX=$(str_repeat 'A' 128)
23928         echo "Create 1K hard links start at $(date)"
23929         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23930                 error "(3) Fail to hard link"
23931
23932         echo "Links count should be right although linkEA overflow"
23933         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23934         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23935         [ $linkcount -eq 1001 ] ||
23936                 error "(5) Unexpected hard links count: $linkcount"
23937
23938         echo "List all links start at $(date)"
23939         ls -l $DIR/$tdir/foo > /dev/null ||
23940                 error "(6) Fail to list $DIR/$tdir/foo"
23941
23942         echo "Unlink hard links start at $(date)"
23943         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23944                 error "(7) Fail to unlink"
23945         echo "Unlink hard links finished at $(date)"
23946 }
23947 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23948
23949 test_410()
23950 {
23951         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23952                 skip "Need client version at least 2.9.59"
23953         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23954                 skip "Need MODULES build"
23955
23956         # Create a file, and stat it from the kernel
23957         local testfile=$DIR/$tfile
23958         touch $testfile
23959
23960         local run_id=$RANDOM
23961         local my_ino=$(stat --format "%i" $testfile)
23962
23963         # Try to insert the module. This will always fail as the
23964         # module is designed to not be inserted.
23965         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23966             &> /dev/null
23967
23968         # Anything but success is a test failure
23969         dmesg | grep -q \
23970             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23971             error "no inode match"
23972 }
23973 run_test 410 "Test inode number returned from kernel thread"
23974
23975 cleanup_test411_cgroup() {
23976         trap 0
23977         rmdir "$1"
23978 }
23979
23980 test_411() {
23981         local cg_basedir=/sys/fs/cgroup/memory
23982         # LU-9966
23983         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23984                 skip "no setup for cgroup"
23985
23986         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23987                 error "test file creation failed"
23988         cancel_lru_locks osc
23989
23990         # Create a very small memory cgroup to force a slab allocation error
23991         local cgdir=$cg_basedir/osc_slab_alloc
23992         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23993         trap "cleanup_test411_cgroup $cgdir" EXIT
23994         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23995         echo 1M > $cgdir/memory.limit_in_bytes
23996
23997         # Should not LBUG, just be killed by oom-killer
23998         # dd will return 0 even allocation failure in some environment.
23999         # So don't check return value
24000         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24001         cleanup_test411_cgroup $cgdir
24002
24003         return 0
24004 }
24005 run_test 411 "Slab allocation error with cgroup does not LBUG"
24006
24007 test_412() {
24008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24009         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24010                 skip "Need server version at least 2.10.55"
24011         fi
24012
24013         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24014                 error "mkdir failed"
24015         $LFS getdirstripe $DIR/$tdir
24016         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24017         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24018                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24019         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24020         [ $stripe_count -eq 2 ] ||
24021                 error "expect 2 get $stripe_count"
24022 }
24023 run_test 412 "mkdir on specific MDTs"
24024
24025 test_qos_mkdir() {
24026         local mkdir_cmd=$1
24027         local stripe_count=$2
24028         local mdts=$(comma_list $(mdts_nodes))
24029
24030         local testdir
24031         local lmv_qos_prio_free
24032         local lmv_qos_threshold_rr
24033         local lmv_qos_maxage
24034         local lod_qos_prio_free
24035         local lod_qos_threshold_rr
24036         local lod_qos_maxage
24037         local count
24038         local i
24039
24040         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24041         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24042         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24043                 head -n1)
24044         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24045         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24046         stack_trap "$LCTL set_param \
24047                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24048         stack_trap "$LCTL set_param \
24049                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24050         stack_trap "$LCTL set_param \
24051                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24052
24053         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24054                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24055         lod_qos_prio_free=${lod_qos_prio_free%%%}
24056         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24057                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24058         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24059         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24060                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24061         stack_trap "do_nodes $mdts $LCTL set_param \
24062                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24063         stack_trap "do_nodes $mdts $LCTL set_param \
24064                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24065                 EXIT
24066         stack_trap "do_nodes $mdts $LCTL set_param \
24067                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24068
24069         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24070         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24071
24072         testdir=$DIR/$tdir-s$stripe_count/rr
24073
24074         local stripe_index=$($LFS getstripe -m $testdir)
24075         local test_mkdir_rr=true
24076
24077         getfattr -d -m dmv $testdir | grep dmv
24078         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24079                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24080
24081                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24082         fi
24083
24084         echo
24085         $test_mkdir_rr &&
24086                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24087                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24088
24089         for i in $(seq $((100 * MDSCOUNT))); do
24090                 eval $mkdir_cmd $testdir/subdir$i ||
24091                         error "$mkdir_cmd subdir$i failed"
24092         done
24093
24094         for i in $(seq $MDSCOUNT); do
24095                 count=$($LFS getdirstripe -i $testdir/* |
24096                                 grep ^$((i - 1))$ | wc -l)
24097                 echo "$count directories created on MDT$((i - 1))"
24098                 if $test_mkdir_rr; then
24099                         (( $count == 100 )) ||
24100                                 error "subdirs are not evenly distributed"
24101                 elif [ $((i - 1)) -eq $stripe_index ]; then
24102                         (( $count == 100 * MDSCOUNT )) ||
24103                                 error "$count subdirs created on MDT$((i - 1))"
24104                 else
24105                         (( $count == 0 )) ||
24106                                 error "$count subdirs created on MDT$((i - 1))"
24107                 fi
24108
24109                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24110                         count=$($LFS getdirstripe $testdir/* |
24111                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24112                         echo "$count stripes created on MDT$((i - 1))"
24113                         # deviation should < 5% of average
24114                         (( $count < 95 * stripe_count )) ||
24115                         (( $count > 105 * stripe_count)) &&
24116                                 error "stripes are not evenly distributed"
24117                 fi
24118         done
24119
24120         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24121         do_nodes $mdts $LCTL set_param \
24122                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24123
24124         echo
24125         echo "Check for uneven MDTs: "
24126
24127         local ffree
24128         local bavail
24129         local max
24130         local min
24131         local max_index
24132         local min_index
24133         local tmp
24134
24135         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24136         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24137         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24138
24139         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24140         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24141         max_index=0
24142         min_index=0
24143         for ((i = 1; i < ${#ffree[@]}; i++)); do
24144                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24145                 if [ $tmp -gt $max ]; then
24146                         max=$tmp
24147                         max_index=$i
24148                 fi
24149                 if [ $tmp -lt $min ]; then
24150                         min=$tmp
24151                         min_index=$i
24152                 fi
24153         done
24154
24155         (( ${ffree[min_index]} == 0 )) &&
24156                 skip "no free files in MDT$min_index"
24157         (( ${ffree[min_index]} > 100000000 )) &&
24158                 skip "too many free files in MDT$min_index"
24159
24160         # Check if we need to generate uneven MDTs
24161         local threshold=50
24162         local diff=$(((max - min) * 100 / min))
24163         local value="$(generate_string 1024)"
24164
24165         while [ $diff -lt $threshold ]; do
24166                 # generate uneven MDTs, create till $threshold% diff
24167                 echo -n "weight diff=$diff% must be > $threshold% ..."
24168                 count=$((${ffree[min_index]} / 10))
24169                 # 50 sec per 10000 files in vm
24170                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24171                         skip "$count files to create"
24172                 echo "Fill MDT$min_index with $count files"
24173                 [ -d $DIR/$tdir-MDT$min_index ] ||
24174                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24175                         error "mkdir $tdir-MDT$min_index failed"
24176                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24177                         error "create d$count failed"
24178
24179                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24180                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24181                 max=$(((${ffree[max_index]} >> 8) * \
24182                         (${bavail[max_index]} * bsize >> 16)))
24183                 min=$(((${ffree[min_index]} >> 8) * \
24184                         (${bavail[min_index]} * bsize >> 16)))
24185                 diff=$(((max - min) * 100 / min))
24186         done
24187
24188         echo "MDT filesfree available: ${ffree[@]}"
24189         echo "MDT blocks available: ${bavail[@]}"
24190         echo "weight diff=$diff%"
24191
24192         echo
24193         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24194
24195         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24196         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24197         # decrease statfs age, so that it can be updated in time
24198         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24199         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24200
24201         sleep 1
24202
24203         testdir=$DIR/$tdir-s$stripe_count/qos
24204
24205         for i in $(seq $((100 * MDSCOUNT))); do
24206                 eval $mkdir_cmd $testdir/subdir$i ||
24207                         error "$mkdir_cmd subdir$i failed"
24208         done
24209
24210         for i in $(seq $MDSCOUNT); do
24211                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24212                         wc -l)
24213                 echo "$count directories created on MDT$((i - 1))"
24214
24215                 if [ $stripe_count -gt 1 ]; then
24216                         count=$($LFS getdirstripe $testdir/* |
24217                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24218                         echo "$count stripes created on MDT$((i - 1))"
24219                 fi
24220         done
24221
24222         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24223         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24224
24225         # D-value should > 10% of averge
24226         (( $max - $min < 10 )) &&
24227                 error "subdirs shouldn't be evenly distributed"
24228
24229         # ditto
24230         if [ $stripe_count -gt 1 ]; then
24231                 max=$($LFS getdirstripe $testdir/* |
24232                         grep -P "^\s+$max_index\t" | wc -l)
24233                 min=$($LFS getdirstripe $testdir/* |
24234                         grep -P "^\s+$min_index\t" | wc -l)
24235                 (( $max - $min < 10 * $stripe_count )) &&
24236                         error "stripes shouldn't be evenly distributed"|| true
24237         fi
24238 }
24239
24240 test_413a() {
24241         [ $MDSCOUNT -lt 2 ] &&
24242                 skip "We need at least 2 MDTs for this test"
24243
24244         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24245                 skip "Need server version at least 2.12.52"
24246
24247         local stripe_count
24248
24249         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24250                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24251                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24252                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24253                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24254         done
24255 }
24256 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24257
24258 test_413b() {
24259         [ $MDSCOUNT -lt 2 ] &&
24260                 skip "We need at least 2 MDTs for this test"
24261
24262         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24263                 skip "Need server version at least 2.12.52"
24264
24265         local testdir
24266         local stripe_count
24267
24268         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24269                 testdir=$DIR/$tdir-s$stripe_count
24270                 mkdir $testdir || error "mkdir $testdir failed"
24271                 mkdir $testdir/rr || error "mkdir rr failed"
24272                 mkdir $testdir/qos || error "mkdir qos failed"
24273                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24274                         $testdir/rr || error "setdirstripe rr failed"
24275                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24276                         error "setdirstripe failed"
24277                 test_qos_mkdir "mkdir" $stripe_count
24278         done
24279 }
24280 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24281
24282 test_413c() {
24283         [ $MDSCOUNT -ge 2 ] ||
24284                 skip "We need at least 2 MDTs for this test"
24285
24286         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24287                 skip "Need server version at least 2.14.50"
24288
24289         local testdir
24290         local inherit
24291         local inherit_rr
24292
24293         testdir=$DIR/${tdir}-s1
24294         mkdir $testdir || error "mkdir $testdir failed"
24295         mkdir $testdir/rr || error "mkdir rr failed"
24296         mkdir $testdir/qos || error "mkdir qos failed"
24297         # default max_inherit is -1, default max_inherit_rr is 0
24298         $LFS setdirstripe -D -c 1 $testdir/rr ||
24299                 error "setdirstripe rr failed"
24300         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24301                 error "setdirstripe qos failed"
24302         test_qos_mkdir "mkdir" 1
24303
24304         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24305         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24306         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24307         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24308         (( $inherit_rr == 0 )) ||
24309                 error "rr/level1 inherit-rr $inherit_rr != 0"
24310
24311         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24312         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24313         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24314         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24315         (( $inherit_rr == 0 )) ||
24316                 error "qos/level1 inherit-rr $inherit_rr !=0"
24317         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24318         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24319                 error "level2 shouldn't have default LMV" || true
24320 }
24321 run_test 413c "mkdir with default LMV max inherit rr"
24322
24323 test_414() {
24324 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24325         $LCTL set_param fail_loc=0x80000521
24326         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24327         rm -f $DIR/$tfile
24328 }
24329 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24330
24331 test_415() {
24332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24333         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24334                 skip "Need server version at least 2.11.52"
24335
24336         # LU-11102
24337         local total
24338         local setattr_pid
24339         local start_time
24340         local end_time
24341         local duration
24342
24343         total=500
24344         # this test may be slow on ZFS
24345         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24346
24347         # though this test is designed for striped directory, let's test normal
24348         # directory too since lock is always saved as CoS lock.
24349         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24350         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24351
24352         (
24353                 while true; do
24354                         touch $DIR/$tdir
24355                 done
24356         ) &
24357         setattr_pid=$!
24358
24359         start_time=$(date +%s)
24360         for i in $(seq $total); do
24361                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24362                         > /dev/null
24363         done
24364         end_time=$(date +%s)
24365         duration=$((end_time - start_time))
24366
24367         kill -9 $setattr_pid
24368
24369         echo "rename $total files took $duration sec"
24370         [ $duration -lt 100 ] || error "rename took $duration sec"
24371 }
24372 run_test 415 "lock revoke is not missing"
24373
24374 test_416() {
24375         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24376                 skip "Need server version at least 2.11.55"
24377
24378         # define OBD_FAIL_OSD_TXN_START    0x19a
24379         do_facet mds1 lctl set_param fail_loc=0x19a
24380
24381         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24382
24383         true
24384 }
24385 run_test 416 "transaction start failure won't cause system hung"
24386
24387 cleanup_417() {
24388         trap 0
24389         do_nodes $(comma_list $(mdts_nodes)) \
24390                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24391         do_nodes $(comma_list $(mdts_nodes)) \
24392                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24393         do_nodes $(comma_list $(mdts_nodes)) \
24394                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24395 }
24396
24397 test_417() {
24398         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24399         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24400                 skip "Need MDS version at least 2.11.56"
24401
24402         trap cleanup_417 RETURN EXIT
24403
24404         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24405         do_nodes $(comma_list $(mdts_nodes)) \
24406                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24407         $LFS migrate -m 0 $DIR/$tdir.1 &&
24408                 error "migrate dir $tdir.1 should fail"
24409
24410         do_nodes $(comma_list $(mdts_nodes)) \
24411                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24412         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24413                 error "create remote dir $tdir.2 should fail"
24414
24415         do_nodes $(comma_list $(mdts_nodes)) \
24416                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24417         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24418                 error "create striped dir $tdir.3 should fail"
24419         true
24420 }
24421 run_test 417 "disable remote dir, striped dir and dir migration"
24422
24423 # Checks that the outputs of df [-i] and lfs df [-i] match
24424 #
24425 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24426 check_lfs_df() {
24427         local dir=$2
24428         local inodes
24429         local df_out
24430         local lfs_df_out
24431         local count
24432         local passed=false
24433
24434         # blocks or inodes
24435         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24436
24437         for count in {1..100}; do
24438                 cancel_lru_locks
24439                 sync; sleep 0.2
24440
24441                 # read the lines of interest
24442                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24443                         error "df $inodes $dir | tail -n +2 failed"
24444                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24445                         error "lfs df $inodes $dir | grep summary: failed"
24446
24447                 # skip first substrings of each output as they are different
24448                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24449                 # compare the two outputs
24450                 passed=true
24451                 for i in {1..5}; do
24452                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24453                 done
24454                 $passed && break
24455         done
24456
24457         if ! $passed; then
24458                 df -P $inodes $dir
24459                 echo
24460                 lfs df $inodes $dir
24461                 error "df and lfs df $1 output mismatch: "      \
24462                       "df ${inodes}: ${df_out[*]}, "            \
24463                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24464         fi
24465 }
24466
24467 test_418() {
24468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24469
24470         local dir=$DIR/$tdir
24471         local numfiles=$((RANDOM % 4096 + 2))
24472         local numblocks=$((RANDOM % 256 + 1))
24473
24474         wait_delete_completed
24475         test_mkdir $dir
24476
24477         # check block output
24478         check_lfs_df blocks $dir
24479         # check inode output
24480         check_lfs_df inodes $dir
24481
24482         # create a single file and retest
24483         echo "Creating a single file and testing"
24484         createmany -o $dir/$tfile- 1 &>/dev/null ||
24485                 error "creating 1 file in $dir failed"
24486         check_lfs_df blocks $dir
24487         check_lfs_df inodes $dir
24488
24489         # create a random number of files
24490         echo "Creating $((numfiles - 1)) files and testing"
24491         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24492                 error "creating $((numfiles - 1)) files in $dir failed"
24493
24494         # write a random number of blocks to the first test file
24495         echo "Writing $numblocks 4K blocks and testing"
24496         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24497                 count=$numblocks &>/dev/null ||
24498                 error "dd to $dir/${tfile}-0 failed"
24499
24500         # retest
24501         check_lfs_df blocks $dir
24502         check_lfs_df inodes $dir
24503
24504         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24505                 error "unlinking $numfiles files in $dir failed"
24506 }
24507 run_test 418 "df and lfs df outputs match"
24508
24509 test_419()
24510 {
24511         local dir=$DIR/$tdir
24512
24513         mkdir -p $dir
24514         touch $dir/file
24515
24516         cancel_lru_locks mdc
24517
24518         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24519         $LCTL set_param fail_loc=0x1410
24520         cat $dir/file
24521         $LCTL set_param fail_loc=0
24522         rm -rf $dir
24523 }
24524 run_test 419 "Verify open file by name doesn't crash kernel"
24525
24526 test_420()
24527 {
24528         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24529                 skip "Need MDS version at least 2.12.53"
24530
24531         local SAVE_UMASK=$(umask)
24532         local dir=$DIR/$tdir
24533         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24534
24535         mkdir -p $dir
24536         umask 0000
24537         mkdir -m03777 $dir/testdir
24538         ls -dn $dir/testdir
24539         # Need to remove trailing '.' when SELinux is enabled
24540         local dirperms=$(ls -dn $dir/testdir |
24541                          awk '{ sub(/\.$/, "", $1); print $1}')
24542         [ $dirperms == "drwxrwsrwt" ] ||
24543                 error "incorrect perms on $dir/testdir"
24544
24545         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24546                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24547         ls -n $dir/testdir/testfile
24548         local fileperms=$(ls -n $dir/testdir/testfile |
24549                           awk '{ sub(/\.$/, "", $1); print $1}')
24550         [ $fileperms == "-rwxr-xr-x" ] ||
24551                 error "incorrect perms on $dir/testdir/testfile"
24552
24553         umask $SAVE_UMASK
24554 }
24555 run_test 420 "clear SGID bit on non-directories for non-members"
24556
24557 test_421a() {
24558         local cnt
24559         local fid1
24560         local fid2
24561
24562         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24563                 skip "Need MDS version at least 2.12.54"
24564
24565         test_mkdir $DIR/$tdir
24566         createmany -o $DIR/$tdir/f 3
24567         cnt=$(ls -1 $DIR/$tdir | wc -l)
24568         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24569
24570         fid1=$(lfs path2fid $DIR/$tdir/f1)
24571         fid2=$(lfs path2fid $DIR/$tdir/f2)
24572         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24573
24574         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24575         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24576
24577         cnt=$(ls -1 $DIR/$tdir | wc -l)
24578         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24579
24580         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24581         createmany -o $DIR/$tdir/f 3
24582         cnt=$(ls -1 $DIR/$tdir | wc -l)
24583         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24584
24585         fid1=$(lfs path2fid $DIR/$tdir/f1)
24586         fid2=$(lfs path2fid $DIR/$tdir/f2)
24587         echo "remove using fsname $FSNAME"
24588         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24589
24590         cnt=$(ls -1 $DIR/$tdir | wc -l)
24591         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24592 }
24593 run_test 421a "simple rm by fid"
24594
24595 test_421b() {
24596         local cnt
24597         local FID1
24598         local FID2
24599
24600         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24601                 skip "Need MDS version at least 2.12.54"
24602
24603         test_mkdir $DIR/$tdir
24604         createmany -o $DIR/$tdir/f 3
24605         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24606         MULTIPID=$!
24607
24608         FID1=$(lfs path2fid $DIR/$tdir/f1)
24609         FID2=$(lfs path2fid $DIR/$tdir/f2)
24610         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24611
24612         kill -USR1 $MULTIPID
24613         wait
24614
24615         cnt=$(ls $DIR/$tdir | wc -l)
24616         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24617 }
24618 run_test 421b "rm by fid on open file"
24619
24620 test_421c() {
24621         local cnt
24622         local FIDS
24623
24624         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24625                 skip "Need MDS version at least 2.12.54"
24626
24627         test_mkdir $DIR/$tdir
24628         createmany -o $DIR/$tdir/f 3
24629         touch $DIR/$tdir/$tfile
24630         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24631         cnt=$(ls -1 $DIR/$tdir | wc -l)
24632         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24633
24634         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24635         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24636
24637         cnt=$(ls $DIR/$tdir | wc -l)
24638         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24639 }
24640 run_test 421c "rm by fid against hardlinked files"
24641
24642 test_421d() {
24643         local cnt
24644         local FIDS
24645
24646         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24647                 skip "Need MDS version at least 2.12.54"
24648
24649         test_mkdir $DIR/$tdir
24650         createmany -o $DIR/$tdir/f 4097
24651         cnt=$(ls -1 $DIR/$tdir | wc -l)
24652         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24653
24654         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24655         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24656
24657         cnt=$(ls $DIR/$tdir | wc -l)
24658         rm -rf $DIR/$tdir
24659         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24660 }
24661 run_test 421d "rmfid en masse"
24662
24663 test_421e() {
24664         local cnt
24665         local FID
24666
24667         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24668         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24669                 skip "Need MDS version at least 2.12.54"
24670
24671         mkdir -p $DIR/$tdir
24672         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24673         createmany -o $DIR/$tdir/striped_dir/f 512
24674         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24675         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24676
24677         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24678                 sed "s/[/][^:]*://g")
24679         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24680
24681         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24682         rm -rf $DIR/$tdir
24683         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24684 }
24685 run_test 421e "rmfid in DNE"
24686
24687 test_421f() {
24688         local cnt
24689         local FID
24690
24691         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24692                 skip "Need MDS version at least 2.12.54"
24693
24694         test_mkdir $DIR/$tdir
24695         touch $DIR/$tdir/f
24696         cnt=$(ls -1 $DIR/$tdir | wc -l)
24697         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24698
24699         FID=$(lfs path2fid $DIR/$tdir/f)
24700         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24701         # rmfid should fail
24702         cnt=$(ls -1 $DIR/$tdir | wc -l)
24703         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24704
24705         chmod a+rw $DIR/$tdir
24706         ls -la $DIR/$tdir
24707         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24708         # rmfid should fail
24709         cnt=$(ls -1 $DIR/$tdir | wc -l)
24710         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24711
24712         rm -f $DIR/$tdir/f
24713         $RUNAS touch $DIR/$tdir/f
24714         FID=$(lfs path2fid $DIR/$tdir/f)
24715         echo "rmfid as root"
24716         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24717         cnt=$(ls -1 $DIR/$tdir | wc -l)
24718         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24719
24720         rm -f $DIR/$tdir/f
24721         $RUNAS touch $DIR/$tdir/f
24722         cnt=$(ls -1 $DIR/$tdir | wc -l)
24723         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24724         FID=$(lfs path2fid $DIR/$tdir/f)
24725         # rmfid w/o user_fid2path mount option should fail
24726         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24727         cnt=$(ls -1 $DIR/$tdir | wc -l)
24728         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24729
24730         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24731         stack_trap "rmdir $tmpdir"
24732         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24733                 error "failed to mount client'"
24734         stack_trap "umount_client $tmpdir"
24735
24736         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24737         # rmfid should succeed
24738         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24739         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24740
24741         # rmfid shouldn't allow to remove files due to dir's permission
24742         chmod a+rwx $tmpdir/$tdir
24743         touch $tmpdir/$tdir/f
24744         ls -la $tmpdir/$tdir
24745         FID=$(lfs path2fid $tmpdir/$tdir/f)
24746         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24747         return 0
24748 }
24749 run_test 421f "rmfid checks permissions"
24750
24751 test_421g() {
24752         local cnt
24753         local FIDS
24754
24755         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24756         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24757                 skip "Need MDS version at least 2.12.54"
24758
24759         mkdir -p $DIR/$tdir
24760         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24761         createmany -o $DIR/$tdir/striped_dir/f 512
24762         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24763         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24764
24765         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24766                 sed "s/[/][^:]*://g")
24767
24768         rm -f $DIR/$tdir/striped_dir/f1*
24769         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24770         removed=$((512 - cnt))
24771
24772         # few files have been just removed, so we expect
24773         # rmfid to fail on their fids
24774         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24775         [ $removed != $errors ] && error "$errors != $removed"
24776
24777         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24778         rm -rf $DIR/$tdir
24779         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24780 }
24781 run_test 421g "rmfid to return errors properly"
24782
24783 test_422() {
24784         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24785         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24786         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24787         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24788         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24789
24790         local amc=$(at_max_get client)
24791         local amo=$(at_max_get mds1)
24792         local timeout=`lctl get_param -n timeout`
24793
24794         at_max_set 0 client
24795         at_max_set 0 mds1
24796
24797 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24798         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24799                         fail_val=$(((2*timeout + 10)*1000))
24800         touch $DIR/$tdir/d3/file &
24801         sleep 2
24802 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24803         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24804                         fail_val=$((2*timeout + 5))
24805         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24806         local pid=$!
24807         sleep 1
24808         kill -9 $pid
24809         sleep $((2 * timeout))
24810         echo kill $pid
24811         kill -9 $pid
24812         lctl mark touch
24813         touch $DIR/$tdir/d2/file3
24814         touch $DIR/$tdir/d2/file4
24815         touch $DIR/$tdir/d2/file5
24816
24817         wait
24818         at_max_set $amc client
24819         at_max_set $amo mds1
24820
24821         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24822         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24823                 error "Watchdog is always throttled"
24824 }
24825 run_test 422 "kill a process with RPC in progress"
24826
24827 stat_test() {
24828     df -h $MOUNT &
24829     df -h $MOUNT &
24830     df -h $MOUNT &
24831     df -h $MOUNT &
24832     df -h $MOUNT &
24833     df -h $MOUNT &
24834 }
24835
24836 test_423() {
24837     local _stats
24838     # ensure statfs cache is expired
24839     sleep 2;
24840
24841     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24842     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24843
24844     return 0
24845 }
24846 run_test 423 "statfs should return a right data"
24847
24848 test_424() {
24849 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24850         $LCTL set_param fail_loc=0x80000522
24851         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24852         rm -f $DIR/$tfile
24853 }
24854 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24855
24856 test_425() {
24857         test_mkdir -c -1 $DIR/$tdir
24858         $LFS setstripe -c -1 $DIR/$tdir
24859
24860         lru_resize_disable "" 100
24861         stack_trap "lru_resize_enable" EXIT
24862
24863         sleep 5
24864
24865         for i in $(seq $((MDSCOUNT * 125))); do
24866                 local t=$DIR/$tdir/$tfile_$i
24867
24868                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24869                         error_noexit "Create file $t"
24870         done
24871         stack_trap "rm -rf $DIR/$tdir" EXIT
24872
24873         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24874                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24875                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24876
24877                 [ $lock_count -le $lru_size ] ||
24878                         error "osc lock count $lock_count > lru size $lru_size"
24879         done
24880
24881         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24882                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24883                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24884
24885                 [ $lock_count -le $lru_size ] ||
24886                         error "mdc lock count $lock_count > lru size $lru_size"
24887         done
24888 }
24889 run_test 425 "lock count should not exceed lru size"
24890
24891 test_426() {
24892         splice-test -r $DIR/$tfile
24893         splice-test -rd $DIR/$tfile
24894         splice-test $DIR/$tfile
24895         splice-test -d $DIR/$tfile
24896 }
24897 run_test 426 "splice test on Lustre"
24898
24899 test_427() {
24900         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24901         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24902                 skip "Need MDS version at least 2.12.4"
24903         local log
24904
24905         mkdir $DIR/$tdir
24906         mkdir $DIR/$tdir/1
24907         mkdir $DIR/$tdir/2
24908         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24909         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24910
24911         $LFS getdirstripe $DIR/$tdir/1/dir
24912
24913         #first setfattr for creating updatelog
24914         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24915
24916 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24917         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24918         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24919         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24920
24921         sleep 2
24922         fail mds2
24923         wait_recovery_complete mds2 $((2*TIMEOUT))
24924
24925         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24926         echo $log | grep "get update log failed" &&
24927                 error "update log corruption is detected" || true
24928 }
24929 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24930
24931 test_428() {
24932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24933         local cache_limit=$CACHE_MAX
24934
24935         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24936         $LCTL set_param -n llite.*.max_cached_mb=64
24937
24938         mkdir $DIR/$tdir
24939         $LFS setstripe -c 1 $DIR/$tdir
24940         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24941         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24942         #test write
24943         for f in $(seq 4); do
24944                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24945         done
24946         wait
24947
24948         cancel_lru_locks osc
24949         # Test read
24950         for f in $(seq 4); do
24951                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24952         done
24953         wait
24954 }
24955 run_test 428 "large block size IO should not hang"
24956
24957 test_429() { # LU-7915 / LU-10948
24958         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24959         local testfile=$DIR/$tfile
24960         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24961         local new_flag=1
24962         local first_rpc
24963         local second_rpc
24964         local third_rpc
24965
24966         $LCTL get_param $ll_opencache_threshold_count ||
24967                 skip "client does not have opencache parameter"
24968
24969         set_opencache $new_flag
24970         stack_trap "restore_opencache"
24971         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24972                 error "enable opencache failed"
24973         touch $testfile
24974         # drop MDC DLM locks
24975         cancel_lru_locks mdc
24976         # clear MDC RPC stats counters
24977         $LCTL set_param $mdc_rpcstats=clear
24978
24979         # According to the current implementation, we need to run 3 times
24980         # open & close file to verify if opencache is enabled correctly.
24981         # 1st, RPCs are sent for lookup/open and open handle is released on
24982         #      close finally.
24983         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24984         #      so open handle won't be released thereafter.
24985         # 3rd, No RPC is sent out.
24986         $MULTIOP $testfile oc || error "multiop failed"
24987         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24988         echo "1st: $first_rpc RPCs in flight"
24989
24990         $MULTIOP $testfile oc || error "multiop failed"
24991         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24992         echo "2nd: $second_rpc RPCs in flight"
24993
24994         $MULTIOP $testfile oc || error "multiop failed"
24995         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24996         echo "3rd: $third_rpc RPCs in flight"
24997
24998         #verify no MDC RPC is sent
24999         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25000 }
25001 run_test 429 "verify if opencache flag on client side does work"
25002
25003 lseek_test_430() {
25004         local offset
25005         local file=$1
25006
25007         # data at [200K, 400K)
25008         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25009                 error "256K->512K dd fails"
25010         # data at [2M, 3M)
25011         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25012                 error "2M->3M dd fails"
25013         # data at [4M, 5M)
25014         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25015                 error "4M->5M dd fails"
25016         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25017         # start at first component hole #1
25018         printf "Seeking hole from 1000 ... "
25019         offset=$(lseek_test -l 1000 $file)
25020         echo $offset
25021         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25022         printf "Seeking data from 1000 ... "
25023         offset=$(lseek_test -d 1000 $file)
25024         echo $offset
25025         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25026
25027         # start at first component data block
25028         printf "Seeking hole from 300000 ... "
25029         offset=$(lseek_test -l 300000 $file)
25030         echo $offset
25031         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25032         printf "Seeking data from 300000 ... "
25033         offset=$(lseek_test -d 300000 $file)
25034         echo $offset
25035         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25036
25037         # start at the first component but beyond end of object size
25038         printf "Seeking hole from 1000000 ... "
25039         offset=$(lseek_test -l 1000000 $file)
25040         echo $offset
25041         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25042         printf "Seeking data from 1000000 ... "
25043         offset=$(lseek_test -d 1000000 $file)
25044         echo $offset
25045         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25046
25047         # start at second component stripe 2 (empty file)
25048         printf "Seeking hole from 1500000 ... "
25049         offset=$(lseek_test -l 1500000 $file)
25050         echo $offset
25051         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25052         printf "Seeking data from 1500000 ... "
25053         offset=$(lseek_test -d 1500000 $file)
25054         echo $offset
25055         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25056
25057         # start at second component stripe 1 (all data)
25058         printf "Seeking hole from 3000000 ... "
25059         offset=$(lseek_test -l 3000000 $file)
25060         echo $offset
25061         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25062         printf "Seeking data from 3000000 ... "
25063         offset=$(lseek_test -d 3000000 $file)
25064         echo $offset
25065         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25066
25067         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25068                 error "2nd dd fails"
25069         echo "Add data block at 640K...1280K"
25070
25071         # start at before new data block, in hole
25072         printf "Seeking hole from 600000 ... "
25073         offset=$(lseek_test -l 600000 $file)
25074         echo $offset
25075         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25076         printf "Seeking data from 600000 ... "
25077         offset=$(lseek_test -d 600000 $file)
25078         echo $offset
25079         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25080
25081         # start at the first component new data block
25082         printf "Seeking hole from 1000000 ... "
25083         offset=$(lseek_test -l 1000000 $file)
25084         echo $offset
25085         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25086         printf "Seeking data from 1000000 ... "
25087         offset=$(lseek_test -d 1000000 $file)
25088         echo $offset
25089         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25090
25091         # start at second component stripe 2, new data
25092         printf "Seeking hole from 1200000 ... "
25093         offset=$(lseek_test -l 1200000 $file)
25094         echo $offset
25095         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25096         printf "Seeking data from 1200000 ... "
25097         offset=$(lseek_test -d 1200000 $file)
25098         echo $offset
25099         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25100
25101         # start beyond file end
25102         printf "Using offset > filesize ... "
25103         lseek_test -l 4000000 $file && error "lseek should fail"
25104         printf "Using offset > filesize ... "
25105         lseek_test -d 4000000 $file && error "lseek should fail"
25106
25107         printf "Done\n\n"
25108 }
25109
25110 test_430a() {
25111         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25112                 skip "MDT does not support SEEK_HOLE"
25113
25114         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25115                 skip "OST does not support SEEK_HOLE"
25116
25117         local file=$DIR/$tdir/$tfile
25118
25119         mkdir -p $DIR/$tdir
25120
25121         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25122         # OST stripe #1 will have continuous data at [1M, 3M)
25123         # OST stripe #2 is empty
25124         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25125         lseek_test_430 $file
25126         rm $file
25127         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25128         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25129         lseek_test_430 $file
25130         rm $file
25131         $LFS setstripe -c2 -S 512K $file
25132         echo "Two stripes, stripe size 512K"
25133         lseek_test_430 $file
25134         rm $file
25135         # FLR with stale mirror
25136         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25137                        -N -c2 -S 1M $file
25138         echo "Mirrored file:"
25139         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25140         echo "Plain 2 stripes 1M"
25141         lseek_test_430 $file
25142         rm $file
25143 }
25144 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25145
25146 test_430b() {
25147         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25148                 skip "OST does not support SEEK_HOLE"
25149
25150         local offset
25151         local file=$DIR/$tdir/$tfile
25152
25153         mkdir -p $DIR/$tdir
25154         # Empty layout lseek should fail
25155         $MCREATE $file
25156         # seek from 0
25157         printf "Seeking hole from 0 ... "
25158         lseek_test -l 0 $file && error "lseek should fail"
25159         printf "Seeking data from 0 ... "
25160         lseek_test -d 0 $file && error "lseek should fail"
25161         rm $file
25162
25163         # 1M-hole file
25164         $LFS setstripe -E 1M -c2 -E eof $file
25165         $TRUNCATE $file 1048576
25166         printf "Seeking hole from 1000000 ... "
25167         offset=$(lseek_test -l 1000000 $file)
25168         echo $offset
25169         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25170         printf "Seeking data from 1000000 ... "
25171         lseek_test -d 1000000 $file && error "lseek should fail"
25172         rm $file
25173
25174         # full component followed by non-inited one
25175         $LFS setstripe -E 1M -c2 -E eof $file
25176         dd if=/dev/urandom of=$file bs=1M count=1
25177         printf "Seeking hole from 1000000 ... "
25178         offset=$(lseek_test -l 1000000 $file)
25179         echo $offset
25180         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25181         printf "Seeking hole from 1048576 ... "
25182         lseek_test -l 1048576 $file && error "lseek should fail"
25183         # init second component and truncate back
25184         echo "123" >> $file
25185         $TRUNCATE $file 1048576
25186         printf "Seeking hole from 1000000 ... "
25187         offset=$(lseek_test -l 1000000 $file)
25188         echo $offset
25189         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25190         printf "Seeking hole from 1048576 ... "
25191         lseek_test -l 1048576 $file && error "lseek should fail"
25192         # boundary checks for big values
25193         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25194         offset=$(lseek_test -d 0 $file.10g)
25195         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25196         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25197         offset=$(lseek_test -d 0 $file.100g)
25198         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25199         return 0
25200 }
25201 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25202
25203 test_430c() {
25204         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25205                 skip "OST does not support SEEK_HOLE"
25206
25207         local file=$DIR/$tdir/$tfile
25208         local start
25209
25210         mkdir -p $DIR/$tdir
25211         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25212
25213         # cp version 8.33+ prefers lseek over fiemap
25214         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25215                 start=$SECONDS
25216                 time cp $file /dev/null
25217                 (( SECONDS - start < 5 )) ||
25218                         error "cp: too long runtime $((SECONDS - start))"
25219
25220         fi
25221         # tar version 1.29+ supports SEEK_HOLE/DATA
25222         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25223                 start=$SECONDS
25224                 time tar cS $file - | cat > /dev/null
25225                 (( SECONDS - start < 5 )) ||
25226                         error "tar: too long runtime $((SECONDS - start))"
25227         fi
25228 }
25229 run_test 430c "lseek: external tools check"
25230
25231 test_431() { # LU-14187
25232         local file=$DIR/$tdir/$tfile
25233
25234         mkdir -p $DIR/$tdir
25235         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25236         dd if=/dev/urandom of=$file bs=4k count=1
25237         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25238         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25239         #define OBD_FAIL_OST_RESTART_IO 0x251
25240         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25241         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25242         cp $file $file.0
25243         cancel_lru_locks
25244         sync_all_data
25245         echo 3 > /proc/sys/vm/drop_caches
25246         diff  $file $file.0 || error "data diff"
25247 }
25248 run_test 431 "Restart transaction for IO"
25249
25250 prep_801() {
25251         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25252         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25253                 skip "Need server version at least 2.9.55"
25254
25255         start_full_debug_logging
25256 }
25257
25258 post_801() {
25259         stop_full_debug_logging
25260 }
25261
25262 barrier_stat() {
25263         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25264                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25265                            awk '/The barrier for/ { print $7 }')
25266                 echo $st
25267         else
25268                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25269                 echo \'$st\'
25270         fi
25271 }
25272
25273 barrier_expired() {
25274         local expired
25275
25276         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25277                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25278                           awk '/will be expired/ { print $7 }')
25279         else
25280                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25281         fi
25282
25283         echo $expired
25284 }
25285
25286 test_801a() {
25287         prep_801
25288
25289         echo "Start barrier_freeze at: $(date)"
25290         #define OBD_FAIL_BARRIER_DELAY          0x2202
25291         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25292         # Do not reduce barrier time - See LU-11873
25293         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25294
25295         sleep 2
25296         local b_status=$(barrier_stat)
25297         echo "Got barrier status at: $(date)"
25298         [ "$b_status" = "'freezing_p1'" ] ||
25299                 error "(1) unexpected barrier status $b_status"
25300
25301         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25302         wait
25303         b_status=$(barrier_stat)
25304         [ "$b_status" = "'frozen'" ] ||
25305                 error "(2) unexpected barrier status $b_status"
25306
25307         local expired=$(barrier_expired)
25308         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25309         sleep $((expired + 3))
25310
25311         b_status=$(barrier_stat)
25312         [ "$b_status" = "'expired'" ] ||
25313                 error "(3) unexpected barrier status $b_status"
25314
25315         # Do not reduce barrier time - See LU-11873
25316         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25317                 error "(4) fail to freeze barrier"
25318
25319         b_status=$(barrier_stat)
25320         [ "$b_status" = "'frozen'" ] ||
25321                 error "(5) unexpected barrier status $b_status"
25322
25323         echo "Start barrier_thaw at: $(date)"
25324         #define OBD_FAIL_BARRIER_DELAY          0x2202
25325         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25326         do_facet mgs $LCTL barrier_thaw $FSNAME &
25327
25328         sleep 2
25329         b_status=$(barrier_stat)
25330         echo "Got barrier status at: $(date)"
25331         [ "$b_status" = "'thawing'" ] ||
25332                 error "(6) unexpected barrier status $b_status"
25333
25334         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25335         wait
25336         b_status=$(barrier_stat)
25337         [ "$b_status" = "'thawed'" ] ||
25338                 error "(7) unexpected barrier status $b_status"
25339
25340         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25341         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25342         do_facet mgs $LCTL barrier_freeze $FSNAME
25343
25344         b_status=$(barrier_stat)
25345         [ "$b_status" = "'failed'" ] ||
25346                 error "(8) unexpected barrier status $b_status"
25347
25348         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25349         do_facet mgs $LCTL barrier_thaw $FSNAME
25350
25351         post_801
25352 }
25353 run_test 801a "write barrier user interfaces and stat machine"
25354
25355 test_801b() {
25356         prep_801
25357
25358         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25359         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25360         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25361         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25362         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25363
25364         cancel_lru_locks mdc
25365
25366         # 180 seconds should be long enough
25367         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25368
25369         local b_status=$(barrier_stat)
25370         [ "$b_status" = "'frozen'" ] ||
25371                 error "(6) unexpected barrier status $b_status"
25372
25373         mkdir $DIR/$tdir/d0/d10 &
25374         mkdir_pid=$!
25375
25376         touch $DIR/$tdir/d1/f13 &
25377         touch_pid=$!
25378
25379         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25380         ln_pid=$!
25381
25382         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25383         mv_pid=$!
25384
25385         rm -f $DIR/$tdir/d4/f12 &
25386         rm_pid=$!
25387
25388         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25389
25390         # To guarantee taht the 'stat' is not blocked
25391         b_status=$(barrier_stat)
25392         [ "$b_status" = "'frozen'" ] ||
25393                 error "(8) unexpected barrier status $b_status"
25394
25395         # let above commands to run at background
25396         sleep 5
25397
25398         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25399         ps -p $touch_pid || error "(10) touch should be blocked"
25400         ps -p $ln_pid || error "(11) link should be blocked"
25401         ps -p $mv_pid || error "(12) rename should be blocked"
25402         ps -p $rm_pid || error "(13) unlink should be blocked"
25403
25404         b_status=$(barrier_stat)
25405         [ "$b_status" = "'frozen'" ] ||
25406                 error "(14) unexpected barrier status $b_status"
25407
25408         do_facet mgs $LCTL barrier_thaw $FSNAME
25409         b_status=$(barrier_stat)
25410         [ "$b_status" = "'thawed'" ] ||
25411                 error "(15) unexpected barrier status $b_status"
25412
25413         wait $mkdir_pid || error "(16) mkdir should succeed"
25414         wait $touch_pid || error "(17) touch should succeed"
25415         wait $ln_pid || error "(18) link should succeed"
25416         wait $mv_pid || error "(19) rename should succeed"
25417         wait $rm_pid || error "(20) unlink should succeed"
25418
25419         post_801
25420 }
25421 run_test 801b "modification will be blocked by write barrier"
25422
25423 test_801c() {
25424         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25425
25426         prep_801
25427
25428         stop mds2 || error "(1) Fail to stop mds2"
25429
25430         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25431
25432         local b_status=$(barrier_stat)
25433         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25434                 do_facet mgs $LCTL barrier_thaw $FSNAME
25435                 error "(2) unexpected barrier status $b_status"
25436         }
25437
25438         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25439                 error "(3) Fail to rescan barrier bitmap"
25440
25441         # Do not reduce barrier time - See LU-11873
25442         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25443
25444         b_status=$(barrier_stat)
25445         [ "$b_status" = "'frozen'" ] ||
25446                 error "(4) unexpected barrier status $b_status"
25447
25448         do_facet mgs $LCTL barrier_thaw $FSNAME
25449         b_status=$(barrier_stat)
25450         [ "$b_status" = "'thawed'" ] ||
25451                 error "(5) unexpected barrier status $b_status"
25452
25453         local devname=$(mdsdevname 2)
25454
25455         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25456
25457         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25458                 error "(7) Fail to rescan barrier bitmap"
25459
25460         post_801
25461 }
25462 run_test 801c "rescan barrier bitmap"
25463
25464 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25465 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25466 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25467 saved_MOUNT_OPTS=$MOUNT_OPTS
25468
25469 cleanup_802a() {
25470         trap 0
25471
25472         stopall
25473         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25474         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25475         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25476         MOUNT_OPTS=$saved_MOUNT_OPTS
25477         setupall
25478 }
25479
25480 test_802a() {
25481         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25482         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25483         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25484                 skip "Need server version at least 2.9.55"
25485
25486         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25487
25488         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25489
25490         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25491                 error "(2) Fail to copy"
25492
25493         trap cleanup_802a EXIT
25494
25495         # sync by force before remount as readonly
25496         sync; sync_all_data; sleep 3; sync_all_data
25497
25498         stopall
25499
25500         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25501         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25502         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25503
25504         echo "Mount the server as read only"
25505         setupall server_only || error "(3) Fail to start servers"
25506
25507         echo "Mount client without ro should fail"
25508         mount_client $MOUNT &&
25509                 error "(4) Mount client without 'ro' should fail"
25510
25511         echo "Mount client with ro should succeed"
25512         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25513         mount_client $MOUNT ||
25514                 error "(5) Mount client with 'ro' should succeed"
25515
25516         echo "Modify should be refused"
25517         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25518
25519         echo "Read should be allowed"
25520         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25521                 error "(7) Read should succeed under ro mode"
25522
25523         cleanup_802a
25524 }
25525 run_test 802a "simulate readonly device"
25526
25527 test_802b() {
25528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25529         remote_mds_nodsh && skip "remote MDS with nodsh"
25530
25531         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25532                 skip "readonly option not available"
25533
25534         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25535
25536         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25537                 error "(2) Fail to copy"
25538
25539         # write back all cached data before setting MDT to readonly
25540         cancel_lru_locks
25541         sync_all_data
25542
25543         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25544         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25545
25546         echo "Modify should be refused"
25547         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25548
25549         echo "Read should be allowed"
25550         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25551                 error "(7) Read should succeed under ro mode"
25552
25553         # disable readonly
25554         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25555 }
25556 run_test 802b "be able to set MDTs to readonly"
25557
25558 test_803a() {
25559         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25560         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25561                 skip "MDS needs to be newer than 2.10.54"
25562
25563         mkdir -p $DIR/$tdir
25564         # Create some objects on all MDTs to trigger related logs objects
25565         for idx in $(seq $MDSCOUNT); do
25566                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25567                         $DIR/$tdir/dir${idx} ||
25568                         error "Fail to create $DIR/$tdir/dir${idx}"
25569         done
25570
25571         sync; sleep 3
25572         wait_delete_completed # ensure old test cleanups are finished
25573         echo "before create:"
25574         $LFS df -i $MOUNT
25575         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25576
25577         for i in {1..10}; do
25578                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25579                         error "Fail to create $DIR/$tdir/foo$i"
25580         done
25581
25582         sync; sleep 3
25583         echo "after create:"
25584         $LFS df -i $MOUNT
25585         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25586
25587         # allow for an llog to be cleaned up during the test
25588         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25589                 error "before ($before_used) + 10 > after ($after_used)"
25590
25591         for i in {1..10}; do
25592                 rm -rf $DIR/$tdir/foo$i ||
25593                         error "Fail to remove $DIR/$tdir/foo$i"
25594         done
25595
25596         sleep 3 # avoid MDT return cached statfs
25597         wait_delete_completed
25598         echo "after unlink:"
25599         $LFS df -i $MOUNT
25600         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25601
25602         # allow for an llog to be created during the test
25603         [ $after_used -le $((before_used + 1)) ] ||
25604                 error "after ($after_used) > before ($before_used) + 1"
25605 }
25606 run_test 803a "verify agent object for remote object"
25607
25608 test_803b() {
25609         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25610         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25611                 skip "MDS needs to be newer than 2.13.56"
25612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25613
25614         for i in $(seq 0 $((MDSCOUNT - 1))); do
25615                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25616         done
25617
25618         local before=0
25619         local after=0
25620
25621         local tmp
25622
25623         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25624         for i in $(seq 0 $((MDSCOUNT - 1))); do
25625                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25626                         awk '/getattr/ { print $2 }')
25627                 before=$((before + tmp))
25628         done
25629         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25630         for i in $(seq 0 $((MDSCOUNT - 1))); do
25631                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25632                         awk '/getattr/ { print $2 }')
25633                 after=$((after + tmp))
25634         done
25635
25636         [ $before -eq $after ] || error "getattr count $before != $after"
25637 }
25638 run_test 803b "remote object can getattr from cache"
25639
25640 test_804() {
25641         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25642         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25643                 skip "MDS needs to be newer than 2.10.54"
25644         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25645
25646         mkdir -p $DIR/$tdir
25647         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25648                 error "Fail to create $DIR/$tdir/dir0"
25649
25650         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25651         local dev=$(mdsdevname 2)
25652
25653         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25654                 grep ${fid} || error "NOT found agent entry for dir0"
25655
25656         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25657                 error "Fail to create $DIR/$tdir/dir1"
25658
25659         touch $DIR/$tdir/dir1/foo0 ||
25660                 error "Fail to create $DIR/$tdir/dir1/foo0"
25661         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25662         local rc=0
25663
25664         for idx in $(seq $MDSCOUNT); do
25665                 dev=$(mdsdevname $idx)
25666                 do_facet mds${idx} \
25667                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25668                         grep ${fid} && rc=$idx
25669         done
25670
25671         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25672                 error "Fail to rename foo0 to foo1"
25673         if [ $rc -eq 0 ]; then
25674                 for idx in $(seq $MDSCOUNT); do
25675                         dev=$(mdsdevname $idx)
25676                         do_facet mds${idx} \
25677                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25678                         grep ${fid} && rc=$idx
25679                 done
25680         fi
25681
25682         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25683                 error "Fail to rename foo1 to foo2"
25684         if [ $rc -eq 0 ]; then
25685                 for idx in $(seq $MDSCOUNT); do
25686                         dev=$(mdsdevname $idx)
25687                         do_facet mds${idx} \
25688                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25689                         grep ${fid} && rc=$idx
25690                 done
25691         fi
25692
25693         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25694
25695         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25696                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25697         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25698                 error "Fail to rename foo2 to foo0"
25699         unlink $DIR/$tdir/dir1/foo0 ||
25700                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25701         rm -rf $DIR/$tdir/dir0 ||
25702                 error "Fail to rm $DIR/$tdir/dir0"
25703
25704         for idx in $(seq $MDSCOUNT); do
25705                 dev=$(mdsdevname $idx)
25706                 rc=0
25707
25708                 stop mds${idx}
25709                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25710                         rc=$?
25711                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25712                         error "mount mds$idx failed"
25713                 df $MOUNT > /dev/null 2>&1
25714
25715                 # e2fsck should not return error
25716                 [ $rc -eq 0 ] ||
25717                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25718         done
25719 }
25720 run_test 804 "verify agent entry for remote entry"
25721
25722 cleanup_805() {
25723         do_facet $SINGLEMDS zfs set quota=$old $fsset
25724         unlinkmany $DIR/$tdir/f- 1000000
25725         trap 0
25726 }
25727
25728 test_805() {
25729         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25730         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25731         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25732                 skip "netfree not implemented before 0.7"
25733         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25734                 skip "Need MDS version at least 2.10.57"
25735
25736         local fsset
25737         local freekb
25738         local usedkb
25739         local old
25740         local quota
25741         local pref="osd-zfs.$FSNAME-MDT0000."
25742
25743         # limit available space on MDS dataset to meet nospace issue
25744         # quickly. then ZFS 0.7.2 can use reserved space if asked
25745         # properly (using netfree flag in osd_declare_destroy()
25746         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25747         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25748                 gawk '{print $3}')
25749         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25750         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25751         let "usedkb=usedkb-freekb"
25752         let "freekb=freekb/2"
25753         if let "freekb > 5000"; then
25754                 let "freekb=5000"
25755         fi
25756         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25757         trap cleanup_805 EXIT
25758         mkdir $DIR/$tdir
25759         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25760                 error "Can't set PFL layout"
25761         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25762         rm -rf $DIR/$tdir || error "not able to remove"
25763         do_facet $SINGLEMDS zfs set quota=$old $fsset
25764         trap 0
25765 }
25766 run_test 805 "ZFS can remove from full fs"
25767
25768 # Size-on-MDS test
25769 check_lsom_data()
25770 {
25771         local file=$1
25772         local expect=$(stat -c %s $file)
25773
25774         check_lsom_size $1 $expect
25775
25776         local blocks=$($LFS getsom -b $file)
25777         expect=$(stat -c %b $file)
25778         [[ $blocks == $expect ]] ||
25779                 error "$file expected blocks: $expect, got: $blocks"
25780 }
25781
25782 check_lsom_size()
25783 {
25784         local size
25785         local expect=$2
25786
25787         cancel_lru_locks mdc
25788
25789         size=$($LFS getsom -s $1)
25790         [[ $size == $expect ]] ||
25791                 error "$file expected size: $expect, got: $size"
25792 }
25793
25794 test_806() {
25795         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25796                 skip "Need MDS version at least 2.11.52"
25797
25798         local bs=1048576
25799
25800         touch $DIR/$tfile || error "touch $tfile failed"
25801
25802         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25803         save_lustre_params client "llite.*.xattr_cache" > $save
25804         lctl set_param llite.*.xattr_cache=0
25805         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25806
25807         # single-threaded write
25808         echo "Test SOM for single-threaded write"
25809         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25810                 error "write $tfile failed"
25811         check_lsom_size $DIR/$tfile $bs
25812
25813         local num=32
25814         local size=$(($num * $bs))
25815         local offset=0
25816         local i
25817
25818         echo "Test SOM for single client multi-threaded($num) write"
25819         $TRUNCATE $DIR/$tfile 0
25820         for ((i = 0; i < $num; i++)); do
25821                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25822                 local pids[$i]=$!
25823                 offset=$((offset + $bs))
25824         done
25825         for (( i=0; i < $num; i++ )); do
25826                 wait ${pids[$i]}
25827         done
25828         check_lsom_size $DIR/$tfile $size
25829
25830         $TRUNCATE $DIR/$tfile 0
25831         for ((i = 0; i < $num; i++)); do
25832                 offset=$((offset - $bs))
25833                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25834                 local pids[$i]=$!
25835         done
25836         for (( i=0; i < $num; i++ )); do
25837                 wait ${pids[$i]}
25838         done
25839         check_lsom_size $DIR/$tfile $size
25840
25841         # multi-client writes
25842         num=$(get_node_count ${CLIENTS//,/ })
25843         size=$(($num * $bs))
25844         offset=0
25845         i=0
25846
25847         echo "Test SOM for multi-client ($num) writes"
25848         $TRUNCATE $DIR/$tfile 0
25849         for client in ${CLIENTS//,/ }; do
25850                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25851                 local pids[$i]=$!
25852                 i=$((i + 1))
25853                 offset=$((offset + $bs))
25854         done
25855         for (( i=0; i < $num; i++ )); do
25856                 wait ${pids[$i]}
25857         done
25858         check_lsom_size $DIR/$tfile $offset
25859
25860         i=0
25861         $TRUNCATE $DIR/$tfile 0
25862         for client in ${CLIENTS//,/ }; do
25863                 offset=$((offset - $bs))
25864                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25865                 local pids[$i]=$!
25866                 i=$((i + 1))
25867         done
25868         for (( i=0; i < $num; i++ )); do
25869                 wait ${pids[$i]}
25870         done
25871         check_lsom_size $DIR/$tfile $size
25872
25873         # verify truncate
25874         echo "Test SOM for truncate"
25875         $TRUNCATE $DIR/$tfile 1048576
25876         check_lsom_size $DIR/$tfile 1048576
25877         $TRUNCATE $DIR/$tfile 1234
25878         check_lsom_size $DIR/$tfile 1234
25879
25880         # verify SOM blocks count
25881         echo "Verify SOM block count"
25882         $TRUNCATE $DIR/$tfile 0
25883         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25884                 error "failed to write file $tfile"
25885         check_lsom_data $DIR/$tfile
25886 }
25887 run_test 806 "Verify Lazy Size on MDS"
25888
25889 test_807() {
25890         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25891         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25892                 skip "Need MDS version at least 2.11.52"
25893
25894         # Registration step
25895         changelog_register || error "changelog_register failed"
25896         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25897         changelog_users $SINGLEMDS | grep -q $cl_user ||
25898                 error "User $cl_user not found in changelog_users"
25899
25900         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25901         save_lustre_params client "llite.*.xattr_cache" > $save
25902         lctl set_param llite.*.xattr_cache=0
25903         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25904
25905         rm -rf $DIR/$tdir || error "rm $tdir failed"
25906         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25907         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25908         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25909         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25910                 error "truncate $tdir/trunc failed"
25911
25912         local bs=1048576
25913         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25914                 error "write $tfile failed"
25915
25916         # multi-client wirtes
25917         local num=$(get_node_count ${CLIENTS//,/ })
25918         local offset=0
25919         local i=0
25920
25921         echo "Test SOM for multi-client ($num) writes"
25922         touch $DIR/$tfile || error "touch $tfile failed"
25923         $TRUNCATE $DIR/$tfile 0
25924         for client in ${CLIENTS//,/ }; do
25925                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25926                 local pids[$i]=$!
25927                 i=$((i + 1))
25928                 offset=$((offset + $bs))
25929         done
25930         for (( i=0; i < $num; i++ )); do
25931                 wait ${pids[$i]}
25932         done
25933
25934         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25935         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25936         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25937         check_lsom_data $DIR/$tdir/trunc
25938         check_lsom_data $DIR/$tdir/single_dd
25939         check_lsom_data $DIR/$tfile
25940
25941         rm -rf $DIR/$tdir
25942         # Deregistration step
25943         changelog_deregister || error "changelog_deregister failed"
25944 }
25945 run_test 807 "verify LSOM syncing tool"
25946
25947 check_som_nologged()
25948 {
25949         local lines=$($LFS changelog $FSNAME-MDT0000 |
25950                 grep 'x=trusted.som' | wc -l)
25951         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25952 }
25953
25954 test_808() {
25955         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25956                 skip "Need MDS version at least 2.11.55"
25957
25958         # Registration step
25959         changelog_register || error "changelog_register failed"
25960
25961         touch $DIR/$tfile || error "touch $tfile failed"
25962         check_som_nologged
25963
25964         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25965                 error "write $tfile failed"
25966         check_som_nologged
25967
25968         $TRUNCATE $DIR/$tfile 1234
25969         check_som_nologged
25970
25971         $TRUNCATE $DIR/$tfile 1048576
25972         check_som_nologged
25973
25974         # Deregistration step
25975         changelog_deregister || error "changelog_deregister failed"
25976 }
25977 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25978
25979 check_som_nodata()
25980 {
25981         $LFS getsom $1
25982         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25983 }
25984
25985 test_809() {
25986         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25987                 skip "Need MDS version at least 2.11.56"
25988
25989         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25990                 error "failed to create DoM-only file $DIR/$tfile"
25991         touch $DIR/$tfile || error "touch $tfile failed"
25992         check_som_nodata $DIR/$tfile
25993
25994         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25995                 error "write $tfile failed"
25996         check_som_nodata $DIR/$tfile
25997
25998         $TRUNCATE $DIR/$tfile 1234
25999         check_som_nodata $DIR/$tfile
26000
26001         $TRUNCATE $DIR/$tfile 4097
26002         check_som_nodata $DIR/$file
26003 }
26004 run_test 809 "Verify no SOM xattr store for DoM-only files"
26005
26006 test_810() {
26007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26008         $GSS && skip_env "could not run with gss"
26009         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26010                 skip "OST < 2.12.58 doesn't align checksum"
26011
26012         set_checksums 1
26013         stack_trap "set_checksums $ORIG_CSUM" EXIT
26014         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26015
26016         local csum
26017         local before
26018         local after
26019         for csum in $CKSUM_TYPES; do
26020                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26021                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26022                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26023                         eval set -- $i
26024                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26025                         before=$(md5sum $DIR/$tfile)
26026                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26027                         after=$(md5sum $DIR/$tfile)
26028                         [ "$before" == "$after" ] ||
26029                                 error "$csum: $before != $after bs=$1 seek=$2"
26030                 done
26031         done
26032 }
26033 run_test 810 "partial page writes on ZFS (LU-11663)"
26034
26035 test_812a() {
26036         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26037                 skip "OST < 2.12.51 doesn't support this fail_loc"
26038
26039         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26040         # ensure ost1 is connected
26041         stat $DIR/$tfile >/dev/null || error "can't stat"
26042         wait_osc_import_state client ost1 FULL
26043         # no locks, no reqs to let the connection idle
26044         cancel_lru_locks osc
26045
26046         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26047 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26048         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26049         wait_osc_import_state client ost1 CONNECTING
26050         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26051
26052         stat $DIR/$tfile >/dev/null || error "can't stat file"
26053 }
26054 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26055
26056 test_812b() { # LU-12378
26057         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26058                 skip "OST < 2.12.51 doesn't support this fail_loc"
26059
26060         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26061         # ensure ost1 is connected
26062         stat $DIR/$tfile >/dev/null || error "can't stat"
26063         wait_osc_import_state client ost1 FULL
26064         # no locks, no reqs to let the connection idle
26065         cancel_lru_locks osc
26066
26067         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26068 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26069         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26070         wait_osc_import_state client ost1 CONNECTING
26071         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26072
26073         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26074         wait_osc_import_state client ost1 IDLE
26075 }
26076 run_test 812b "do not drop no resend request for idle connect"
26077
26078 test_812c() {
26079         local old
26080
26081         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26082
26083         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26084         $LFS getstripe $DIR/$tfile
26085         $LCTL set_param osc.*.idle_timeout=10
26086         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26087         # ensure ost1 is connected
26088         stat $DIR/$tfile >/dev/null || error "can't stat"
26089         wait_osc_import_state client ost1 FULL
26090         # no locks, no reqs to let the connection idle
26091         cancel_lru_locks osc
26092
26093 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26094         $LCTL set_param fail_loc=0x80000533
26095         sleep 15
26096         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26097 }
26098 run_test 812c "idle import vs lock enqueue race"
26099
26100 test_813() {
26101         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26102         [ -z "$file_heat_sav" ] && skip "no file heat support"
26103
26104         local readsample
26105         local writesample
26106         local readbyte
26107         local writebyte
26108         local readsample1
26109         local writesample1
26110         local readbyte1
26111         local writebyte1
26112
26113         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26114         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26115
26116         $LCTL set_param -n llite.*.file_heat=1
26117         echo "Turn on file heat"
26118         echo "Period second: $period_second, Decay percentage: $decay_pct"
26119
26120         echo "QQQQ" > $DIR/$tfile
26121         echo "QQQQ" > $DIR/$tfile
26122         echo "QQQQ" > $DIR/$tfile
26123         cat $DIR/$tfile > /dev/null
26124         cat $DIR/$tfile > /dev/null
26125         cat $DIR/$tfile > /dev/null
26126         cat $DIR/$tfile > /dev/null
26127
26128         local out=$($LFS heat_get $DIR/$tfile)
26129
26130         $LFS heat_get $DIR/$tfile
26131         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26132         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26133         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26134         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26135
26136         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26137         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26138         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26139         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26140
26141         sleep $((period_second + 3))
26142         echo "Sleep $((period_second + 3)) seconds..."
26143         # The recursion formula to calculate the heat of the file f is as
26144         # follow:
26145         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26146         # Where Hi is the heat value in the period between time points i*I and
26147         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26148         # to the weight of Ci.
26149         out=$($LFS heat_get $DIR/$tfile)
26150         $LFS heat_get $DIR/$tfile
26151         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26152         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26153         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26154         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26155
26156         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26157                 error "read sample ($readsample) is wrong"
26158         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26159                 error "write sample ($writesample) is wrong"
26160         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26161                 error "read bytes ($readbyte) is wrong"
26162         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26163                 error "write bytes ($writebyte) is wrong"
26164
26165         echo "QQQQ" > $DIR/$tfile
26166         echo "QQQQ" > $DIR/$tfile
26167         echo "QQQQ" > $DIR/$tfile
26168         cat $DIR/$tfile > /dev/null
26169         cat $DIR/$tfile > /dev/null
26170         cat $DIR/$tfile > /dev/null
26171         cat $DIR/$tfile > /dev/null
26172
26173         sleep $((period_second + 3))
26174         echo "Sleep $((period_second + 3)) seconds..."
26175
26176         out=$($LFS heat_get $DIR/$tfile)
26177         $LFS heat_get $DIR/$tfile
26178         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26179         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26180         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26181         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26182
26183         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26184                 4 * $decay_pct) / 100") -eq 1 ] ||
26185                 error "read sample ($readsample1) is wrong"
26186         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26187                 3 * $decay_pct) / 100") -eq 1 ] ||
26188                 error "write sample ($writesample1) is wrong"
26189         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26190                 20 * $decay_pct) / 100") -eq 1 ] ||
26191                 error "read bytes ($readbyte1) is wrong"
26192         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26193                 15 * $decay_pct) / 100") -eq 1 ] ||
26194                 error "write bytes ($writebyte1) is wrong"
26195
26196         echo "Turn off file heat for the file $DIR/$tfile"
26197         $LFS heat_set -o $DIR/$tfile
26198
26199         echo "QQQQ" > $DIR/$tfile
26200         echo "QQQQ" > $DIR/$tfile
26201         echo "QQQQ" > $DIR/$tfile
26202         cat $DIR/$tfile > /dev/null
26203         cat $DIR/$tfile > /dev/null
26204         cat $DIR/$tfile > /dev/null
26205         cat $DIR/$tfile > /dev/null
26206
26207         out=$($LFS heat_get $DIR/$tfile)
26208         $LFS heat_get $DIR/$tfile
26209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26213
26214         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26215         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26216         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26217         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26218
26219         echo "Trun on file heat for the file $DIR/$tfile"
26220         $LFS heat_set -O $DIR/$tfile
26221
26222         echo "QQQQ" > $DIR/$tfile
26223         echo "QQQQ" > $DIR/$tfile
26224         echo "QQQQ" > $DIR/$tfile
26225         cat $DIR/$tfile > /dev/null
26226         cat $DIR/$tfile > /dev/null
26227         cat $DIR/$tfile > /dev/null
26228         cat $DIR/$tfile > /dev/null
26229
26230         out=$($LFS heat_get $DIR/$tfile)
26231         $LFS heat_get $DIR/$tfile
26232         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26233         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26234         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26235         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26236
26237         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26238         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26239         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26240         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26241
26242         $LFS heat_set -c $DIR/$tfile
26243         $LCTL set_param -n llite.*.file_heat=0
26244         echo "Turn off file heat support for the Lustre filesystem"
26245
26246         echo "QQQQ" > $DIR/$tfile
26247         echo "QQQQ" > $DIR/$tfile
26248         echo "QQQQ" > $DIR/$tfile
26249         cat $DIR/$tfile > /dev/null
26250         cat $DIR/$tfile > /dev/null
26251         cat $DIR/$tfile > /dev/null
26252         cat $DIR/$tfile > /dev/null
26253
26254         out=$($LFS heat_get $DIR/$tfile)
26255         $LFS heat_get $DIR/$tfile
26256         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26257         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26258         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26259         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26260
26261         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26262         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26263         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26264         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26265
26266         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26267         rm -f $DIR/$tfile
26268 }
26269 run_test 813 "File heat verfication"
26270
26271 test_814()
26272 {
26273         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26274         echo -n y >> $DIR/$tfile
26275         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26276         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26277 }
26278 run_test 814 "sparse cp works as expected (LU-12361)"
26279
26280 test_815()
26281 {
26282         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26283         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26284 }
26285 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26286
26287 test_816() {
26288         local ost1_imp=$(get_osc_import_name client ost1)
26289         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26290                          cut -d'.' -f2)
26291
26292         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26293         # ensure ost1 is connected
26294
26295         stat $DIR/$tfile >/dev/null || error "can't stat"
26296         wait_osc_import_state client ost1 FULL
26297         # no locks, no reqs to let the connection idle
26298         cancel_lru_locks osc
26299         lru_resize_disable osc
26300         local before
26301         local now
26302         before=$($LCTL get_param -n \
26303                  ldlm.namespaces.$imp_name.lru_size)
26304
26305         wait_osc_import_state client ost1 IDLE
26306         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26307         now=$($LCTL get_param -n \
26308               ldlm.namespaces.$imp_name.lru_size)
26309         [ $before == $now ] || error "lru_size changed $before != $now"
26310 }
26311 run_test 816 "do not reset lru_resize on idle reconnect"
26312
26313 cleanup_817() {
26314         umount $tmpdir
26315         exportfs -u localhost:$DIR/nfsexp
26316         rm -rf $DIR/nfsexp
26317 }
26318
26319 test_817() {
26320         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26321
26322         mkdir -p $DIR/nfsexp
26323         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26324                 error "failed to export nfs"
26325
26326         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26327         stack_trap cleanup_817 EXIT
26328
26329         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26330                 error "failed to mount nfs to $tmpdir"
26331
26332         cp /bin/true $tmpdir
26333         $DIR/nfsexp/true || error "failed to execute 'true' command"
26334 }
26335 run_test 817 "nfsd won't cache write lock for exec file"
26336
26337 test_818() {
26338         mkdir $DIR/$tdir
26339         $LFS setstripe -c1 -i0 $DIR/$tfile
26340         $LFS setstripe -c1 -i1 $DIR/$tfile
26341         stop $SINGLEMDS
26342         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26343         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26344         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26345                 error "start $SINGLEMDS failed"
26346         rm -rf $DIR/$tdir
26347 }
26348 run_test 818 "unlink with failed llog"
26349
26350 test_819a() {
26351         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26352         cancel_lru_locks osc
26353         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26354         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26355         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26356         rm -f $TDIR/$tfile
26357 }
26358 run_test 819a "too big niobuf in read"
26359
26360 test_819b() {
26361         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26362         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26363         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26364         cancel_lru_locks osc
26365         sleep 1
26366         rm -f $TDIR/$tfile
26367 }
26368 run_test 819b "too big niobuf in write"
26369
26370
26371 function test_820_start_ost() {
26372         sleep 5
26373
26374         for num in $(seq $OSTCOUNT); do
26375                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26376         done
26377 }
26378
26379 test_820() {
26380         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26381
26382         mkdir $DIR/$tdir
26383         umount_client $MOUNT || error "umount failed"
26384         for num in $(seq $OSTCOUNT); do
26385                 stop ost$num
26386         done
26387
26388         # mount client with no active OSTs
26389         # so that the client can't initialize max LOV EA size
26390         # from OSC notifications
26391         mount_client $MOUNT || error "mount failed"
26392         # delay OST starting to keep this 0 max EA size for a while
26393         test_820_start_ost &
26394
26395         # create a directory on MDS2
26396         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26397                 error "Failed to create directory"
26398         # open intent should update default EA size
26399         # see mdc_update_max_ea_from_body()
26400         # notice this is the very first RPC to MDS2
26401         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26402         ret=$?
26403         echo $out
26404         # With SSK, this situation can lead to -EPERM being returned.
26405         # In that case, simply retry.
26406         if [ $ret -ne 0 ] && $SHARED_KEY; then
26407                 if echo "$out" | grep -q "not permitted"; then
26408                         cp /etc/services $DIR/$tdir/mds2
26409                         ret=$?
26410                 fi
26411         fi
26412         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26413 }
26414 run_test 820 "update max EA from open intent"
26415
26416 test_822() {
26417         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26418
26419         save_lustre_params mds1 \
26420                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26421         do_facet $SINGLEMDS "$LCTL set_param -n \
26422                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26423         do_facet $SINGLEMDS "$LCTL set_param -n \
26424                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26425
26426         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26427         local maxage=$(do_facet mds1 $LCTL get_param -n \
26428                        osp.$FSNAME-OST0000*MDT0000.maxage)
26429         sleep $((maxage + 1))
26430
26431         #define OBD_FAIL_NET_ERROR_RPC          0x532
26432         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26433
26434         stack_trap "restore_lustre_params < $p; rm $p"
26435
26436         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26437                       osp.$FSNAME-OST0000*MDT0000.create_count")
26438         for i in $(seq 1 $count); do
26439                 touch $DIR/$tfile.${i} || error "touch failed"
26440         done
26441 }
26442 run_test 822 "test precreate failure"
26443
26444 #
26445 # tests that do cleanup/setup should be run at the end
26446 #
26447
26448 test_900() {
26449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26450         local ls
26451
26452         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26453         $LCTL set_param fail_loc=0x903
26454
26455         cancel_lru_locks MGC
26456
26457         FAIL_ON_ERROR=true cleanup
26458         FAIL_ON_ERROR=true setup
26459 }
26460 run_test 900 "umount should not race with any mgc requeue thread"
26461
26462 # LUS-6253/LU-11185
26463 test_901() {
26464         local oldc
26465         local newc
26466         local olds
26467         local news
26468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26469
26470         # some get_param have a bug to handle dot in param name
26471         cancel_lru_locks MGC
26472         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26473         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26474         umount_client $MOUNT || error "umount failed"
26475         mount_client $MOUNT || error "mount failed"
26476         cancel_lru_locks MGC
26477         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26478         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26479
26480         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26481         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26482
26483         return 0
26484 }
26485 run_test 901 "don't leak a mgc lock on client umount"
26486
26487 # LU-13377
26488 test_902() {
26489         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26490                 skip "client does not have LU-13377 fix"
26491         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26492         $LCTL set_param fail_loc=0x1415
26493         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26494         cancel_lru_locks osc
26495         rm -f $DIR/$tfile
26496 }
26497 run_test 902 "test short write doesn't hang lustre"
26498
26499 complete $SECONDS
26500 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26501 check_and_cleanup_lustre
26502 if [ "$I_MOUNTED" != "yes" ]; then
26503         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26504 fi
26505 exit_status