Whamcloud - gitweb
865cac448248c714b9fd853965bf9d10cbd76f46
[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 # createtest also checks that device nodes are created and
3323 # then visible correctly (#2091)
3324 test_28() { # bug 2091
3325         test_mkdir $DIR/d28
3326         $CREATETEST $DIR/d28/ct || error "createtest failed"
3327 }
3328 run_test 28 "create/mknod/mkdir with bad file types ============"
3329
3330 test_29() {
3331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3332
3333         sync; sleep 1; sync # flush out any dirty pages from previous tests
3334         cancel_lru_locks
3335         test_mkdir $DIR/d29
3336         touch $DIR/d29/foo
3337         log 'first d29'
3338         ls -l $DIR/d29
3339
3340         declare -i LOCKCOUNTORIG=0
3341         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3342                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3343         done
3344         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3345
3346         declare -i LOCKUNUSEDCOUNTORIG=0
3347         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3348                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3349         done
3350
3351         log 'second d29'
3352         ls -l $DIR/d29
3353         log 'done'
3354
3355         declare -i LOCKCOUNTCURRENT=0
3356         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3357                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3358         done
3359
3360         declare -i LOCKUNUSEDCOUNTCURRENT=0
3361         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3362                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3363         done
3364
3365         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3366                 $LCTL set_param -n ldlm.dump_namespaces ""
3367                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3368                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3369                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3370                 return 2
3371         fi
3372         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3373                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3374                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3375                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3376                 return 3
3377         fi
3378 }
3379 run_test 29 "IT_GETATTR regression  ============================"
3380
3381 test_30a() { # was test_30
3382         cp $(which ls) $DIR || cp /bin/ls $DIR
3383         $DIR/ls / || error "Can't execute binary from lustre"
3384         rm $DIR/ls
3385 }
3386 run_test 30a "execute binary from Lustre (execve) =============="
3387
3388 test_30b() {
3389         cp `which ls` $DIR || cp /bin/ls $DIR
3390         chmod go+rx $DIR/ls
3391         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3392         rm $DIR/ls
3393 }
3394 run_test 30b "execute binary from Lustre as non-root ==========="
3395
3396 test_30c() { # b=22376
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3398
3399         cp $(which ls) $DIR || cp /bin/ls $DIR
3400         chmod a-rw $DIR/ls
3401         cancel_lru_locks mdc
3402         cancel_lru_locks osc
3403         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3404         rm -f $DIR/ls
3405 }
3406 run_test 30c "execute binary from Lustre without read perms ===="
3407
3408 test_30d() {
3409         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3410
3411         for i in {1..10}; do
3412                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3413                 local PID=$!
3414                 sleep 1
3415                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3416                 wait $PID || error "executing dd from Lustre failed"
3417                 rm -f $DIR/$tfile
3418         done
3419
3420         rm -f $DIR/dd
3421 }
3422 run_test 30d "execute binary from Lustre while clear locks"
3423
3424 test_31a() {
3425         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3426         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3427 }
3428 run_test 31a "open-unlink file =================================="
3429
3430 test_31b() {
3431         touch $DIR/f31 || error "touch $DIR/f31 failed"
3432         ln $DIR/f31 $DIR/f31b || error "ln failed"
3433         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3434         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3435 }
3436 run_test 31b "unlink file with multiple links while open ======="
3437
3438 test_31c() {
3439         touch $DIR/f31 || error "touch $DIR/f31 failed"
3440         ln $DIR/f31 $DIR/f31c || error "ln failed"
3441         multiop_bg_pause $DIR/f31 O_uc ||
3442                 error "multiop_bg_pause for $DIR/f31 failed"
3443         MULTIPID=$!
3444         $MULTIOP $DIR/f31c Ouc
3445         kill -USR1 $MULTIPID
3446         wait $MULTIPID
3447 }
3448 run_test 31c "open-unlink file with multiple links ============="
3449
3450 test_31d() {
3451         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3452         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3453 }
3454 run_test 31d "remove of open directory ========================="
3455
3456 test_31e() { # bug 2904
3457         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3458 }
3459 run_test 31e "remove of open non-empty directory ==============="
3460
3461 test_31f() { # bug 4554
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         set -vx
3465         test_mkdir $DIR/d31f
3466         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3467         cp /etc/hosts $DIR/d31f
3468         ls -l $DIR/d31f
3469         $LFS getstripe $DIR/d31f/hosts
3470         multiop_bg_pause $DIR/d31f D_c || return 1
3471         MULTIPID=$!
3472
3473         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3474         test_mkdir $DIR/d31f
3475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3476         cp /etc/hosts $DIR/d31f
3477         ls -l $DIR/d31f
3478         $LFS getstripe $DIR/d31f/hosts
3479         multiop_bg_pause $DIR/d31f D_c || return 1
3480         MULTIPID2=$!
3481
3482         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3483         wait $MULTIPID || error "first opendir $MULTIPID failed"
3484
3485         sleep 6
3486
3487         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3488         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3489         set +vx
3490 }
3491 run_test 31f "remove of open directory with open-unlink file ==="
3492
3493 test_31g() {
3494         echo "-- cross directory link --"
3495         test_mkdir -c1 $DIR/${tdir}ga
3496         test_mkdir -c1 $DIR/${tdir}gb
3497         touch $DIR/${tdir}ga/f
3498         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3499         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3500         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3501         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3502         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3503 }
3504 run_test 31g "cross directory link==============="
3505
3506 test_31h() {
3507         echo "-- cross directory link --"
3508         test_mkdir -c1 $DIR/${tdir}
3509         test_mkdir -c1 $DIR/${tdir}/dir
3510         touch $DIR/${tdir}/f
3511         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3512         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3513         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3514         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3515         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3516 }
3517 run_test 31h "cross directory link under child==============="
3518
3519 test_31i() {
3520         echo "-- cross directory link --"
3521         test_mkdir -c1 $DIR/$tdir
3522         test_mkdir -c1 $DIR/$tdir/dir
3523         touch $DIR/$tdir/dir/f
3524         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3525         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3526         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3527         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3528         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3529 }
3530 run_test 31i "cross directory link under parent==============="
3531
3532 test_31j() {
3533         test_mkdir -c1 -p $DIR/$tdir
3534         test_mkdir -c1 -p $DIR/$tdir/dir1
3535         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3536         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3537         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3538         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3539         return 0
3540 }
3541 run_test 31j "link for directory==============="
3542
3543 test_31k() {
3544         test_mkdir -c1 -p $DIR/$tdir
3545         touch $DIR/$tdir/s
3546         touch $DIR/$tdir/exist
3547         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3548         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3549         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3550         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3551         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3552         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3553         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3554         return 0
3555 }
3556 run_test 31k "link to file: the same, non-existing, dir==============="
3557
3558 test_31m() {
3559         mkdir $DIR/d31m
3560         touch $DIR/d31m/s
3561         mkdir $DIR/d31m2
3562         touch $DIR/d31m2/exist
3563         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3564         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3565         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3566         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3567         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3568         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3569         return 0
3570 }
3571 run_test 31m "link to file: the same, non-existing, dir==============="
3572
3573 test_31n() {
3574         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3575         nlink=$(stat --format=%h $DIR/$tfile)
3576         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3577         local fd=$(free_fd)
3578         local cmd="exec $fd<$DIR/$tfile"
3579         eval $cmd
3580         cmd="exec $fd<&-"
3581         trap "eval $cmd" EXIT
3582         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3583         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3584         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3585         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3586         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3587         eval $cmd
3588 }
3589 run_test 31n "check link count of unlinked file"
3590
3591 link_one() {
3592         local tempfile=$(mktemp $1_XXXXXX)
3593         mlink $tempfile $1 2> /dev/null &&
3594                 echo "$BASHPID: link $tempfile to $1 succeeded"
3595         munlink $tempfile
3596 }
3597
3598 test_31o() { # LU-2901
3599         test_mkdir $DIR/$tdir
3600         for LOOP in $(seq 100); do
3601                 rm -f $DIR/$tdir/$tfile*
3602                 for THREAD in $(seq 8); do
3603                         link_one $DIR/$tdir/$tfile.$LOOP &
3604                 done
3605                 wait
3606                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3607                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3608                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3609                         break || true
3610         done
3611 }
3612 run_test 31o "duplicate hard links with same filename"
3613
3614 test_31p() {
3615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3616
3617         test_mkdir $DIR/$tdir
3618         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3619         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3620
3621         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3622                 error "open unlink test1 failed"
3623         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3624                 error "open unlink test2 failed"
3625
3626         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3627                 error "test1 still exists"
3628         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3629                 error "test2 still exists"
3630 }
3631 run_test 31p "remove of open striped directory"
3632
3633 test_31q() {
3634         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3635
3636         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3637         index=$($LFS getdirstripe -i $DIR/$tdir)
3638         [ $index -eq 3 ] || error "first stripe index $index != 3"
3639         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3640         [ $index -eq 1 ] || error "second stripe index $index != 1"
3641
3642         # when "-c <stripe_count>" is set, the number of MDTs specified after
3643         # "-i" should equal to the stripe count
3644         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3645 }
3646 run_test 31q "create striped directory on specific MDTs"
3647
3648 cleanup_test32_mount() {
3649         local rc=0
3650         trap 0
3651         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3652         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3653         losetup -d $loopdev || true
3654         rm -rf $DIR/$tdir
3655         return $rc
3656 }
3657
3658 test_32a() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         echo "== more mountpoints and symlinks ================="
3662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3663         trap cleanup_test32_mount EXIT
3664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3665         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3666                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3667         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3668                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3669         cleanup_test32_mount
3670 }
3671 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3672
3673 test_32b() {
3674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3675
3676         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3677         trap cleanup_test32_mount EXIT
3678         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3679         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3680                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3681         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3682                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3683         cleanup_test32_mount
3684 }
3685 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3686
3687 test_32c() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3691         trap cleanup_test32_mount EXIT
3692         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3693         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3694                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3695         test_mkdir -p $DIR/$tdir/d2/test_dir
3696         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3697                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3698         cleanup_test32_mount
3699 }
3700 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3701
3702 test_32d() {
3703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3704
3705         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3706         trap cleanup_test32_mount EXIT
3707         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3708         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3709                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3710         test_mkdir -p $DIR/$tdir/d2/test_dir
3711         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3712                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3713         cleanup_test32_mount
3714 }
3715 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3716
3717 test_32e() {
3718         rm -fr $DIR/$tdir
3719         test_mkdir -p $DIR/$tdir/tmp
3720         local tmp_dir=$DIR/$tdir/tmp
3721         ln -s $DIR/$tdir $tmp_dir/symlink11
3722         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3723         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3724         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3725 }
3726 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3727
3728 test_32f() {
3729         rm -fr $DIR/$tdir
3730         test_mkdir -p $DIR/$tdir/tmp
3731         local tmp_dir=$DIR/$tdir/tmp
3732         ln -s $DIR/$tdir $tmp_dir/symlink11
3733         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3734         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3735         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3736 }
3737 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3738
3739 test_32g() {
3740         local tmp_dir=$DIR/$tdir/tmp
3741         test_mkdir -p $tmp_dir
3742         test_mkdir $DIR/${tdir}2
3743         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3744         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3745         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3746         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3747         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3748         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3749 }
3750 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3751
3752 test_32h() {
3753         rm -fr $DIR/$tdir $DIR/${tdir}2
3754         tmp_dir=$DIR/$tdir/tmp
3755         test_mkdir -p $tmp_dir
3756         test_mkdir $DIR/${tdir}2
3757         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3758         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3759         ls $tmp_dir/symlink12 || error "listing symlink12"
3760         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3761 }
3762 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3763
3764 test_32i() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3768         trap cleanup_test32_mount EXIT
3769         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3770         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3771                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3772         touch $DIR/$tdir/test_file
3773         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3774                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3778
3779 test_32j() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         touch $DIR/$tdir/test_file
3788         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3789                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3790         cleanup_test32_mount
3791 }
3792 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3793
3794 test_32k() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         rm -fr $DIR/$tdir
3798         trap cleanup_test32_mount EXIT
3799         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3800         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3801                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3802         test_mkdir -p $DIR/$tdir/d2
3803         touch $DIR/$tdir/d2/test_file || error "touch failed"
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3809
3810 test_32l() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         test_mkdir -p $DIR/$tdir/d2
3819         touch $DIR/$tdir/d2/test_file || error "touch failed"
3820         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3825
3826 test_32m() {
3827         rm -fr $DIR/d32m
3828         test_mkdir -p $DIR/d32m/tmp
3829         TMP_DIR=$DIR/d32m/tmp
3830         ln -s $DIR $TMP_DIR/symlink11
3831         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3832         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3833                 error "symlink11 not a link"
3834         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3835                 error "symlink01 not a link"
3836 }
3837 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3838
3839 test_32n() {
3840         rm -fr $DIR/d32n
3841         test_mkdir -p $DIR/d32n/tmp
3842         TMP_DIR=$DIR/d32n/tmp
3843         ln -s $DIR $TMP_DIR/symlink11
3844         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3845         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3846         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3847 }
3848 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3849
3850 test_32o() {
3851         touch $DIR/$tfile
3852         test_mkdir -p $DIR/d32o/tmp
3853         TMP_DIR=$DIR/d32o/tmp
3854         ln -s $DIR/$tfile $TMP_DIR/symlink12
3855         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3856         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3857                 error "symlink12 not a link"
3858         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3859         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3860                 error "$DIR/d32o/tmp/symlink12 not file type"
3861         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3862                 error "$DIR/d32o/symlink02 not file type"
3863 }
3864 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3865
3866 test_32p() {
3867         log 32p_1
3868         rm -fr $DIR/d32p
3869         log 32p_2
3870         rm -f $DIR/$tfile
3871         log 32p_3
3872         touch $DIR/$tfile
3873         log 32p_4
3874         test_mkdir -p $DIR/d32p/tmp
3875         log 32p_5
3876         TMP_DIR=$DIR/d32p/tmp
3877         log 32p_6
3878         ln -s $DIR/$tfile $TMP_DIR/symlink12
3879         log 32p_7
3880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3881         log 32p_8
3882         cat $DIR/d32p/tmp/symlink12 ||
3883                 error "Can't open $DIR/d32p/tmp/symlink12"
3884         log 32p_9
3885         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3886         log 32p_10
3887 }
3888 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3889
3890 test_32q() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3900         cleanup_test32_mount
3901 }
3902 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3903
3904 test_32r() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3914         cleanup_test32_mount
3915 }
3916 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3917
3918 test_33aa() {
3919         rm -f $DIR/$tfile
3920         touch $DIR/$tfile
3921         chmod 444 $DIR/$tfile
3922         chown $RUNAS_ID $DIR/$tfile
3923         log 33_1
3924         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3925         log 33_2
3926 }
3927 run_test 33aa "write file with mode 444 (should return error)"
3928
3929 test_33a() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir $DIR/$tdir
3932         chown $RUNAS_ID $DIR/$tdir
3933         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3934                 error "$RUNAS create $tdir/$tfile failed"
3935         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3936                 error "open RDWR" || true
3937 }
3938 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3939
3940 test_33b() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir $DIR/$tdir
3943         chown $RUNAS_ID $DIR/$tdir
3944         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3945 }
3946 run_test 33b "test open file with malformed flags (No panic)"
3947
3948 test_33c() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         remote_ost_nodsh && skip "remote OST with nodsh"
3951
3952         local ostnum
3953         local ostname
3954         local write_bytes
3955         local all_zeros
3956
3957         all_zeros=:
3958         rm -fr $DIR/$tdir
3959         test_mkdir $DIR/$tdir
3960         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3961
3962         sync
3963         for ostnum in $(seq $OSTCOUNT); do
3964                 # test-framework's OST numbering is one-based, while Lustre's
3965                 # is zero-based
3966                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3967                 # Parsing llobdstat's output sucks; we could grep the /proc
3968                 # path, but that's likely to not be as portable as using the
3969                 # llobdstat utility.  So we parse lctl output instead.
3970                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3971                         obdfilter/$ostname/stats |
3972                         awk '/^write_bytes/ {print $7}' )
3973                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3974                 if (( ${write_bytes:-0} > 0 ))
3975                 then
3976                         all_zeros=false
3977                         break;
3978                 fi
3979         done
3980
3981         $all_zeros || return 0
3982
3983         # Write four bytes
3984         echo foo > $DIR/$tdir/bar
3985         # Really write them
3986         sync
3987
3988         # Total up write_bytes after writing.  We'd better find non-zeros.
3989         for ostnum in $(seq $OSTCOUNT); do
3990                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3991                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3992                         obdfilter/$ostname/stats |
3993                         awk '/^write_bytes/ {print $7}' )
3994                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3995                 if (( ${write_bytes:-0} > 0 ))
3996                 then
3997                         all_zeros=false
3998                         break;
3999                 fi
4000         done
4001
4002         if $all_zeros
4003         then
4004                 for ostnum in $(seq $OSTCOUNT); do
4005                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4006                         echo "Check that write_bytes is present in obdfilter/*/stats:"
4007                         do_facet ost$ostnum lctl get_param -n \
4008                                 obdfilter/$ostname/stats
4009                 done
4010                 error "OST not keeping write_bytes stats (b22312)"
4011         fi
4012 }
4013 run_test 33c "test llobdstat and write_bytes"
4014
4015 test_33d() {
4016         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         local MDTIDX=1
4020         local remote_dir=$DIR/$tdir/remote_dir
4021
4022         test_mkdir $DIR/$tdir
4023         $LFS mkdir -i $MDTIDX $remote_dir ||
4024                 error "create remote directory failed"
4025
4026         touch $remote_dir/$tfile
4027         chmod 444 $remote_dir/$tfile
4028         chown $RUNAS_ID $remote_dir/$tfile
4029
4030         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4031
4032         chown $RUNAS_ID $remote_dir
4033         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4034                                         error "create" || true
4035         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4036                                     error "open RDWR" || true
4037         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4038 }
4039 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4040
4041 test_33e() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043
4044         mkdir $DIR/$tdir
4045
4046         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4047         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4048         mkdir $DIR/$tdir/local_dir
4049
4050         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4051         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4052         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4053
4054         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4055                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4056
4057         rmdir $DIR/$tdir/* || error "rmdir failed"
4058
4059         umask 777
4060         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4061         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4062         mkdir $DIR/$tdir/local_dir
4063
4064         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4065         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4066         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4067
4068         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4069                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4070
4071         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4072
4073         umask 000
4074         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4075         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4076         mkdir $DIR/$tdir/local_dir
4077
4078         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4079         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4080         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4081
4082         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4083                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4084 }
4085 run_test 33e "mkdir and striped directory should have same mode"
4086
4087 cleanup_33f() {
4088         trap 0
4089         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4090 }
4091
4092 test_33f() {
4093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4094         remote_mds_nodsh && skip "remote MDS with nodsh"
4095
4096         mkdir $DIR/$tdir
4097         chmod go+rwx $DIR/$tdir
4098         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4099         trap cleanup_33f EXIT
4100
4101         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4102                 error "cannot create striped directory"
4103
4104         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4105                 error "cannot create files in striped directory"
4106
4107         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4108                 error "cannot remove files in striped directory"
4109
4110         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4111                 error "cannot remove striped directory"
4112
4113         cleanup_33f
4114 }
4115 run_test 33f "nonroot user can create, access, and remove a striped directory"
4116
4117 test_33g() {
4118         mkdir -p $DIR/$tdir/dir2
4119
4120         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4121         echo $err
4122         [[ $err =~ "exists" ]] || error "Not exists error"
4123 }
4124 run_test 33g "nonroot user create already existing root created file"
4125
4126 test_33h() {
4127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4128         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4129                 skip "Need MDS version at least 2.13.50"
4130
4131         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4132                 error "mkdir $tdir failed"
4133         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4134
4135         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4136         local index2
4137
4138         for fname in $DIR/$tdir/$tfile.bak \
4139                      $DIR/$tdir/$tfile.SAV \
4140                      $DIR/$tdir/$tfile.orig \
4141                      $DIR/$tdir/$tfile~; do
4142                 touch $fname  || error "touch $fname failed"
4143                 index2=$($LFS getstripe -m $fname)
4144                 [ $index -eq $index2 ] ||
4145                         error "$fname MDT index mismatch $index != $index2"
4146         done
4147
4148         local failed=0
4149         for i in {1..250}; do
4150                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4151                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4152                         touch $fname  || error "touch $fname failed"
4153                         index2=$($LFS getstripe -m $fname)
4154                         if [[ $index != $index2 ]]; then
4155                                 failed=$((failed + 1))
4156                                 echo "$fname MDT index mismatch $index != $index2"
4157                         fi
4158                 done
4159         done
4160         echo "$failed MDT index mismatches"
4161         (( failed < 20 )) || error "MDT index mismatch $failed times"
4162
4163 }
4164 run_test 33h "temp file is located on the same MDT as target"
4165
4166 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4167 test_34a() {
4168         rm -f $DIR/f34
4169         $MCREATE $DIR/f34 || error "mcreate failed"
4170         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4171                 error "getstripe failed"
4172         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4173         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4174                 error "getstripe failed"
4175         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4176                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4177 }
4178 run_test 34a "truncate file that has not been opened ==========="
4179
4180 test_34b() {
4181         [ ! -f $DIR/f34 ] && test_34a
4182         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4183                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4184         $OPENFILE -f O_RDONLY $DIR/f34
4185         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4186                 error "getstripe failed"
4187         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4188                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4189 }
4190 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4191
4192 test_34c() {
4193         [ ! -f $DIR/f34 ] && test_34a
4194         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4195                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4196         $OPENFILE -f O_RDWR $DIR/f34
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4198                 error "$LFS getstripe failed"
4199         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4200                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4201 }
4202 run_test 34c "O_RDWR opening file-with-size works =============="
4203
4204 test_34d() {
4205         [ ! -f $DIR/f34 ] && test_34a
4206         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4207                 error "dd failed"
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         rm $DIR/f34
4211 }
4212 run_test 34d "write to sparse file ============================="
4213
4214 test_34e() {
4215         rm -f $DIR/f34e
4216         $MCREATE $DIR/f34e || error "mcreate failed"
4217         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4218         $CHECKSTAT -s 1000 $DIR/f34e ||
4219                 error "Size of $DIR/f34e not equal to 1000 bytes"
4220         $OPENFILE -f O_RDWR $DIR/f34e
4221         $CHECKSTAT -s 1000 $DIR/f34e ||
4222                 error "Size of $DIR/f34e not equal to 1000 bytes"
4223 }
4224 run_test 34e "create objects, some with size and some without =="
4225
4226 test_34f() { # bug 6242, 6243
4227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4228
4229         SIZE34F=48000
4230         rm -f $DIR/f34f
4231         $MCREATE $DIR/f34f || error "mcreate failed"
4232         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4233         dd if=$DIR/f34f of=$TMP/f34f
4234         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4235         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4236         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4237         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4238         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4239 }
4240 run_test 34f "read from a file with no objects until EOF ======="
4241
4242 test_34g() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4246                 error "dd failed"
4247         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4248         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4249                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4250         cancel_lru_locks osc
4251         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4252                 error "wrong size after lock cancel"
4253
4254         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4255         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4256                 error "expanding truncate failed"
4257         cancel_lru_locks osc
4258         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4259                 error "wrong expanded size after lock cancel"
4260 }
4261 run_test 34g "truncate long file ==============================="
4262
4263 test_34h() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265
4266         local gid=10
4267         local sz=1000
4268
4269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4270         sync # Flush the cache so that multiop below does not block on cache
4271              # flush when getting the group lock
4272         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4273         MULTIPID=$!
4274
4275         # Since just timed wait is not good enough, let's do a sync write
4276         # that way we are sure enough time for a roundtrip + processing
4277         # passed + 2 seconds of extra margin.
4278         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4279         rm $DIR/${tfile}-1
4280         sleep 2
4281
4282         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4283                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4284                 kill -9 $MULTIPID
4285         fi
4286         wait $MULTIPID
4287         local nsz=`stat -c %s $DIR/$tfile`
4288         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4289 }
4290 run_test 34h "ftruncate file under grouplock should not block"
4291
4292 test_35a() {
4293         cp /bin/sh $DIR/f35a
4294         chmod 444 $DIR/f35a
4295         chown $RUNAS_ID $DIR/f35a
4296         $RUNAS $DIR/f35a && error || true
4297         rm $DIR/f35a
4298 }
4299 run_test 35a "exec file with mode 444 (should return and not leak)"
4300
4301 test_36a() {
4302         rm -f $DIR/f36
4303         utime $DIR/f36 || error "utime failed for MDS"
4304 }
4305 run_test 36a "MDS utime check (mknod, utime)"
4306
4307 test_36b() {
4308         echo "" > $DIR/f36
4309         utime $DIR/f36 || error "utime failed for OST"
4310 }
4311 run_test 36b "OST utime check (open, utime)"
4312
4313 test_36c() {
4314         rm -f $DIR/d36/f36
4315         test_mkdir $DIR/d36
4316         chown $RUNAS_ID $DIR/d36
4317         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4318 }
4319 run_test 36c "non-root MDS utime check (mknod, utime)"
4320
4321 test_36d() {
4322         [ ! -d $DIR/d36 ] && test_36c
4323         echo "" > $DIR/d36/f36
4324         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4325 }
4326 run_test 36d "non-root OST utime check (open, utime)"
4327
4328 test_36e() {
4329         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4330
4331         test_mkdir $DIR/$tdir
4332         touch $DIR/$tdir/$tfile
4333         $RUNAS utime $DIR/$tdir/$tfile &&
4334                 error "utime worked, expected failure" || true
4335 }
4336 run_test 36e "utime on non-owned file (should return error)"
4337
4338 subr_36fh() {
4339         local fl="$1"
4340         local LANG_SAVE=$LANG
4341         local LC_LANG_SAVE=$LC_LANG
4342         export LANG=C LC_LANG=C # for date language
4343
4344         DATESTR="Dec 20  2000"
4345         test_mkdir $DIR/$tdir
4346         lctl set_param fail_loc=$fl
4347         date; date +%s
4348         cp /etc/hosts $DIR/$tdir/$tfile
4349         sync & # write RPC generated with "current" inode timestamp, but delayed
4350         sleep 1
4351         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4352         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4353         cancel_lru_locks $OSC
4354         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4355         date; date +%s
4356         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4357                 echo "BEFORE: $LS_BEFORE" && \
4358                 echo "AFTER : $LS_AFTER" && \
4359                 echo "WANT  : $DATESTR" && \
4360                 error "$DIR/$tdir/$tfile timestamps changed" || true
4361
4362         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4363 }
4364
4365 test_36f() {
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4369         subr_36fh "0x80000214"
4370 }
4371 run_test 36f "utime on file racing with OST BRW write =========="
4372
4373 test_36g() {
4374         remote_ost_nodsh && skip "remote OST with nodsh"
4375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4376         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4377                 skip "Need MDS version at least 2.12.51"
4378
4379         local fmd_max_age
4380         local fmd
4381         local facet="ost1"
4382         local tgt="obdfilter"
4383
4384         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4385
4386         test_mkdir $DIR/$tdir
4387         fmd_max_age=$(do_facet $facet \
4388                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4389                 head -n 1")
4390
4391         echo "FMD max age: ${fmd_max_age}s"
4392         touch $DIR/$tdir/$tfile
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD before: $fmd"
4396         [[ $fmd == 0 ]] &&
4397                 error "FMD wasn't create by touch"
4398         sleep $((fmd_max_age + 12))
4399         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4400                 gawk '{cnt=cnt+$1}  END{print cnt}')
4401         echo "FMD after: $fmd"
4402         [[ $fmd == 0 ]] ||
4403                 error "FMD wasn't expired by ping"
4404 }
4405 run_test 36g "FMD cache expiry ====================="
4406
4407 test_36h() {
4408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4409
4410         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4411         subr_36fh "0x80000227"
4412 }
4413 run_test 36h "utime on file racing with OST BRW write =========="
4414
4415 test_36i() {
4416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4417
4418         test_mkdir $DIR/$tdir
4419         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4420
4421         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4422         local new_mtime=$((mtime + 200))
4423
4424         #change Modify time of striped dir
4425         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4426                         error "change mtime failed"
4427
4428         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4429
4430         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4431 }
4432 run_test 36i "change mtime on striped directory"
4433
4434 # test_37 - duplicate with tests 32q 32r
4435
4436 test_38() {
4437         local file=$DIR/$tfile
4438         touch $file
4439         openfile -f O_DIRECTORY $file
4440         local RC=$?
4441         local ENOTDIR=20
4442         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4443         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4444 }
4445 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4446
4447 test_39a() { # was test_39
4448         touch $DIR/$tfile
4449         touch $DIR/${tfile}2
4450 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4451 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4452 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4453         sleep 2
4454         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4455         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4456                 echo "mtime"
4457                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4458                 echo "atime"
4459                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4460                 echo "ctime"
4461                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4462                 error "O_TRUNC didn't change timestamps"
4463         fi
4464 }
4465 run_test 39a "mtime changed on create"
4466
4467 test_39b() {
4468         test_mkdir -c1 $DIR/$tdir
4469         cp -p /etc/passwd $DIR/$tdir/fopen
4470         cp -p /etc/passwd $DIR/$tdir/flink
4471         cp -p /etc/passwd $DIR/$tdir/funlink
4472         cp -p /etc/passwd $DIR/$tdir/frename
4473         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4474
4475         sleep 1
4476         echo "aaaaaa" >> $DIR/$tdir/fopen
4477         echo "aaaaaa" >> $DIR/$tdir/flink
4478         echo "aaaaaa" >> $DIR/$tdir/funlink
4479         echo "aaaaaa" >> $DIR/$tdir/frename
4480
4481         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4482         local link_new=`stat -c %Y $DIR/$tdir/flink`
4483         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4484         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4485
4486         cat $DIR/$tdir/fopen > /dev/null
4487         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4488         rm -f $DIR/$tdir/funlink2
4489         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4490
4491         for (( i=0; i < 2; i++ )) ; do
4492                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4493                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4494                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4495                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4496
4497                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4498                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4499                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4500                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4501
4502                 cancel_lru_locks $OSC
4503                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4504         done
4505 }
4506 run_test 39b "mtime change on open, link, unlink, rename  ======"
4507
4508 # this should be set to past
4509 TEST_39_MTIME=`date -d "1 year ago" +%s`
4510
4511 # bug 11063
4512 test_39c() {
4513         touch $DIR1/$tfile
4514         sleep 2
4515         local mtime0=`stat -c %Y $DIR1/$tfile`
4516
4517         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4518         local mtime1=`stat -c %Y $DIR1/$tfile`
4519         [ "$mtime1" = $TEST_39_MTIME ] || \
4520                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4521
4522         local d1=`date +%s`
4523         echo hello >> $DIR1/$tfile
4524         local d2=`date +%s`
4525         local mtime2=`stat -c %Y $DIR1/$tfile`
4526         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4527                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4528
4529         mv $DIR1/$tfile $DIR1/$tfile-1
4530
4531         for (( i=0; i < 2; i++ )) ; do
4532                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4533                 [ "$mtime2" = "$mtime3" ] || \
4534                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4535
4536                 cancel_lru_locks $OSC
4537                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4538         done
4539 }
4540 run_test 39c "mtime change on rename ==========================="
4541
4542 # bug 21114
4543 test_39d() {
4544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4545
4546         touch $DIR1/$tfile
4547         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4548
4549         for (( i=0; i < 2; i++ )) ; do
4550                 local mtime=`stat -c %Y $DIR1/$tfile`
4551                 [ $mtime = $TEST_39_MTIME ] || \
4552                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4553
4554                 cancel_lru_locks $OSC
4555                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4556         done
4557 }
4558 run_test 39d "create, utime, stat =============================="
4559
4560 # bug 21114
4561 test_39e() {
4562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4563
4564         touch $DIR1/$tfile
4565         local mtime1=`stat -c %Y $DIR1/$tfile`
4566
4567         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4568
4569         for (( i=0; i < 2; i++ )) ; do
4570                 local mtime2=`stat -c %Y $DIR1/$tfile`
4571                 [ $mtime2 = $TEST_39_MTIME ] || \
4572                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4573
4574                 cancel_lru_locks $OSC
4575                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4576         done
4577 }
4578 run_test 39e "create, stat, utime, stat ========================"
4579
4580 # bug 21114
4581 test_39f() {
4582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4583
4584         touch $DIR1/$tfile
4585         mtime1=`stat -c %Y $DIR1/$tfile`
4586
4587         sleep 2
4588         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4589
4590         for (( i=0; i < 2; i++ )) ; do
4591                 local mtime2=`stat -c %Y $DIR1/$tfile`
4592                 [ $mtime2 = $TEST_39_MTIME ] || \
4593                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4594
4595                 cancel_lru_locks $OSC
4596                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4597         done
4598 }
4599 run_test 39f "create, stat, sleep, utime, stat ================="
4600
4601 # bug 11063
4602 test_39g() {
4603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4604
4605         echo hello >> $DIR1/$tfile
4606         local mtime1=`stat -c %Y $DIR1/$tfile`
4607
4608         sleep 2
4609         chmod o+r $DIR1/$tfile
4610
4611         for (( i=0; i < 2; i++ )) ; do
4612                 local mtime2=`stat -c %Y $DIR1/$tfile`
4613                 [ "$mtime1" = "$mtime2" ] || \
4614                         error "lost mtime: $mtime2, should be $mtime1"
4615
4616                 cancel_lru_locks $OSC
4617                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4618         done
4619 }
4620 run_test 39g "write, chmod, stat ==============================="
4621
4622 # bug 11063
4623 test_39h() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         touch $DIR1/$tfile
4627         sleep 1
4628
4629         local d1=`date`
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4634         local d2=`date`
4635         if [ "$d1" != "$d2" ]; then
4636                 echo "write and touch not within one second"
4637         else
4638                 for (( i=0; i < 2; i++ )) ; do
4639                         local mtime2=`stat -c %Y $DIR1/$tfile`
4640                         [ "$mtime2" = $TEST_39_MTIME ] || \
4641                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4642
4643                         cancel_lru_locks $OSC
4644                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645                 done
4646         fi
4647 }
4648 run_test 39h "write, utime within one second, stat ============="
4649
4650 test_39i() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         mv $DIR1/$tfile $DIR1/$tfile-1
4660
4661         for (( i=0; i < 2; i++ )) ; do
4662                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4663
4664                 [ "$mtime1" = "$mtime2" ] || \
4665                         error "lost mtime: $mtime2, should be $mtime1"
4666
4667                 cancel_lru_locks $OSC
4668                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4669         done
4670 }
4671 run_test 39i "write, rename, stat =============================="
4672
4673 test_39j() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         start_full_debug_logging
4677         touch $DIR1/$tfile
4678         sleep 1
4679
4680         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4681         lctl set_param fail_loc=0x80000412
4682         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4683                 error "multiop failed"
4684         local multipid=$!
4685         local mtime1=`stat -c %Y $DIR1/$tfile`
4686
4687         mv $DIR1/$tfile $DIR1/$tfile-1
4688
4689         kill -USR1 $multipid
4690         wait $multipid || error "multiop close failed"
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4694                 [ "$mtime1" = "$mtime2" ] ||
4695                         error "mtime is lost on close: $mtime2, " \
4696                               "should be $mtime1"
4697
4698                 cancel_lru_locks
4699                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4700         done
4701         lctl set_param fail_loc=0
4702         stop_full_debug_logging
4703 }
4704 run_test 39j "write, rename, close, stat ======================="
4705
4706 test_39k() {
4707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4708
4709         touch $DIR1/$tfile
4710         sleep 1
4711
4712         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4713         local multipid=$!
4714         local mtime1=`stat -c %Y $DIR1/$tfile`
4715
4716         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4717
4718         kill -USR1 $multipid
4719         wait $multipid || error "multiop close failed"
4720
4721         for (( i=0; i < 2; i++ )) ; do
4722                 local mtime2=`stat -c %Y $DIR1/$tfile`
4723
4724                 [ "$mtime2" = $TEST_39_MTIME ] || \
4725                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4726
4727                 cancel_lru_locks
4728                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4729         done
4730 }
4731 run_test 39k "write, utime, close, stat ========================"
4732
4733 # this should be set to future
4734 TEST_39_ATIME=`date -d "1 year" +%s`
4735
4736 test_39l() {
4737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4738         remote_mds_nodsh && skip "remote MDS with nodsh"
4739
4740         local atime_diff=$(do_facet $SINGLEMDS \
4741                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4742         rm -rf $DIR/$tdir
4743         mkdir -p $DIR/$tdir
4744
4745         # test setting directory atime to future
4746         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4747         local atime=$(stat -c %X $DIR/$tdir)
4748         [ "$atime" = $TEST_39_ATIME ] ||
4749                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4750
4751         # test setting directory atime from future to now
4752         local now=$(date +%s)
4753         touch -a -d @$now $DIR/$tdir
4754
4755         atime=$(stat -c %X $DIR/$tdir)
4756         [ "$atime" -eq "$now"  ] ||
4757                 error "atime is not updated from future: $atime, $now"
4758
4759         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4760         sleep 3
4761
4762         # test setting directory atime when now > dir atime + atime_diff
4763         local d1=$(date +%s)
4764         ls $DIR/$tdir
4765         local d2=$(date +%s)
4766         cancel_lru_locks mdc
4767         atime=$(stat -c %X $DIR/$tdir)
4768         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4769                 error "atime is not updated  : $atime, should be $d2"
4770
4771         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4772         sleep 3
4773
4774         # test not setting directory atime when now < dir atime + atime_diff
4775         ls $DIR/$tdir
4776         cancel_lru_locks mdc
4777         atime=$(stat -c %X $DIR/$tdir)
4778         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4779                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4780
4781         do_facet $SINGLEMDS \
4782                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4783 }
4784 run_test 39l "directory atime update ==========================="
4785
4786 test_39m() {
4787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4788
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local far_past_mtime=$(date -d "May 29 1953" +%s)
4792         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4793
4794         touch -m -d @$far_past_mtime $DIR1/$tfile
4795         touch -a -d @$far_past_atime $DIR1/$tfile
4796
4797         for (( i=0; i < 2; i++ )) ; do
4798                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4799                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4800                         error "atime or mtime set incorrectly"
4801
4802                 cancel_lru_locks $OSC
4803                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4804         done
4805 }
4806 run_test 39m "test atime and mtime before 1970"
4807
4808 test_39n() { # LU-3832
4809         remote_mds_nodsh && skip "remote MDS with nodsh"
4810
4811         local atime_diff=$(do_facet $SINGLEMDS \
4812                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4813         local atime0
4814         local atime1
4815         local atime2
4816
4817         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4818
4819         rm -rf $DIR/$tfile
4820         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4821         atime0=$(stat -c %X $DIR/$tfile)
4822
4823         sleep 5
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime1=$(stat -c %X $DIR/$tfile)
4826
4827         sleep 5
4828         cancel_lru_locks mdc
4829         cancel_lru_locks osc
4830         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4831         atime2=$(stat -c %X $DIR/$tfile)
4832
4833         do_facet $SINGLEMDS \
4834                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4835
4836         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4837         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4838 }
4839 run_test 39n "check that O_NOATIME is honored"
4840
4841 test_39o() {
4842         TESTDIR=$DIR/$tdir/$tfile
4843         [ -e $TESTDIR ] && rm -rf $TESTDIR
4844         mkdir -p $TESTDIR
4845         cd $TESTDIR
4846         links1=2
4847         ls
4848         mkdir a b
4849         ls
4850         links2=$(stat -c %h .)
4851         [ $(($links1 + 2)) != $links2 ] &&
4852                 error "wrong links count $(($links1 + 2)) != $links2"
4853         rmdir b
4854         links3=$(stat -c %h .)
4855         [ $(($links1 + 1)) != $links3 ] &&
4856                 error "wrong links count $links1 != $links3"
4857         return 0
4858 }
4859 run_test 39o "directory cached attributes updated after create"
4860
4861 test_39p() {
4862         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4863
4864         local MDTIDX=1
4865         TESTDIR=$DIR/$tdir/$tdir
4866         [ -e $TESTDIR ] && rm -rf $TESTDIR
4867         test_mkdir -p $TESTDIR
4868         cd $TESTDIR
4869         links1=2
4870         ls
4871         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4872         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4873         ls
4874         links2=$(stat -c %h .)
4875         [ $(($links1 + 2)) != $links2 ] &&
4876                 error "wrong links count $(($links1 + 2)) != $links2"
4877         rmdir remote_dir2
4878         links3=$(stat -c %h .)
4879         [ $(($links1 + 1)) != $links3 ] &&
4880                 error "wrong links count $links1 != $links3"
4881         return 0
4882 }
4883 run_test 39p "remote directory cached attributes updated after create ========"
4884
4885 test_39r() {
4886         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4887                 skip "no atime update on old OST"
4888         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4889                 skip_env "ldiskfs only test"
4890         fi
4891
4892         local saved_adiff
4893         saved_adiff=$(do_facet ost1 \
4894                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4895         stack_trap "do_facet ost1 \
4896                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4897
4898         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4899
4900         $LFS setstripe -i 0 $DIR/$tfile
4901         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4902                 error "can't write initial file"
4903         cancel_lru_locks osc
4904
4905         # exceed atime_diff and access file
4906         sleep 6
4907         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4908                 error "can't udpate atime"
4909
4910         local atime_cli=$(stat -c %X $DIR/$tfile)
4911         echo "client atime: $atime_cli"
4912         # allow atime update to be written to device
4913         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4914         sleep 5
4915
4916         local ostdev=$(ostdevname 1)
4917         local fid=($(lfs getstripe -y $DIR/$tfile |
4918                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4919         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4920         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4921
4922         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4923         local atime_ost=$(do_facet ost1 "$cmd" |&
4924                           awk -F'[: ]' '/atime:/ { print $4 }')
4925         (( atime_cli == atime_ost )) ||
4926                 error "atime on client $atime_cli != ost $atime_ost"
4927 }
4928 run_test 39r "lazy atime update on OST"
4929
4930 test_39q() { # LU-8041
4931         local testdir=$DIR/$tdir
4932         mkdir -p $testdir
4933         multiop_bg_pause $testdir D_c || error "multiop failed"
4934         local multipid=$!
4935         cancel_lru_locks mdc
4936         kill -USR1 $multipid
4937         local atime=$(stat -c %X $testdir)
4938         [ "$atime" -ne 0 ] || error "atime is zero"
4939 }
4940 run_test 39q "close won't zero out atime"
4941
4942 test_40() {
4943         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4944         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4945                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4946         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4947                 error "$tfile is not 4096 bytes in size"
4948 }
4949 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4950
4951 test_41() {
4952         # bug 1553
4953         small_write $DIR/f41 18
4954 }
4955 run_test 41 "test small file write + fstat ====================="
4956
4957 count_ost_writes() {
4958         lctl get_param -n ${OSC}.*.stats |
4959                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4960                         END { printf("%0.0f", writes) }'
4961 }
4962
4963 # decent default
4964 WRITEBACK_SAVE=500
4965 DIRTY_RATIO_SAVE=40
4966 MAX_DIRTY_RATIO=50
4967 BG_DIRTY_RATIO_SAVE=10
4968 MAX_BG_DIRTY_RATIO=25
4969
4970 start_writeback() {
4971         trap 0
4972         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4973         # dirty_ratio, dirty_background_ratio
4974         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4975                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4976                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4977                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4978         else
4979                 # if file not here, we are a 2.4 kernel
4980                 kill -CONT `pidof kupdated`
4981         fi
4982 }
4983
4984 stop_writeback() {
4985         # setup the trap first, so someone cannot exit the test at the
4986         # exact wrong time and mess up a machine
4987         trap start_writeback EXIT
4988         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4989         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4990                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4991                 sysctl -w vm.dirty_writeback_centisecs=0
4992                 sysctl -w vm.dirty_writeback_centisecs=0
4993                 # save and increase /proc/sys/vm/dirty_ratio
4994                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4995                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4996                 # save and increase /proc/sys/vm/dirty_background_ratio
4997                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4998                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4999         else
5000                 # if file not here, we are a 2.4 kernel
5001                 kill -STOP `pidof kupdated`
5002         fi
5003 }
5004
5005 # ensure that all stripes have some grant before we test client-side cache
5006 setup_test42() {
5007         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5008                 dd if=/dev/zero of=$i bs=4k count=1
5009                 rm $i
5010         done
5011 }
5012
5013 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5014 # file truncation, and file removal.
5015 test_42a() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         setup_test42
5019         cancel_lru_locks $OSC
5020         stop_writeback
5021         sync; sleep 1; sync # just to be safe
5022         BEFOREWRITES=`count_ost_writes`
5023         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5024         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5025         AFTERWRITES=`count_ost_writes`
5026         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5027                 error "$BEFOREWRITES < $AFTERWRITES"
5028         start_writeback
5029 }
5030 run_test 42a "ensure that we don't flush on close"
5031
5032 test_42b() {
5033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5034
5035         setup_test42
5036         cancel_lru_locks $OSC
5037         stop_writeback
5038         sync
5039         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5040         BEFOREWRITES=$(count_ost_writes)
5041         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5045         fi
5046         BEFOREWRITES=$(count_ost_writes)
5047         sync || error "sync: $?"
5048         AFTERWRITES=$(count_ost_writes)
5049         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5050                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5051         fi
5052         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5053         start_writeback
5054         return 0
5055 }
5056 run_test 42b "test destroy of file with cached dirty data ======"
5057
5058 # if these tests just want to test the effect of truncation,
5059 # they have to be very careful.  consider:
5060 # - the first open gets a {0,EOF}PR lock
5061 # - the first write conflicts and gets a {0, count-1}PW
5062 # - the rest of the writes are under {count,EOF}PW
5063 # - the open for truncate tries to match a {0,EOF}PR
5064 #   for the filesize and cancels the PWs.
5065 # any number of fixes (don't get {0,EOF} on open, match
5066 # composite locks, do smarter file size management) fix
5067 # this, but for now we want these tests to verify that
5068 # the cancellation with truncate intent works, so we
5069 # start the file with a full-file pw lock to match against
5070 # until the truncate.
5071 trunc_test() {
5072         test=$1
5073         file=$DIR/$test
5074         offset=$2
5075         cancel_lru_locks $OSC
5076         stop_writeback
5077         # prime the file with 0,EOF PW to match
5078         touch $file
5079         $TRUNCATE $file 0
5080         sync; sync
5081         # now the real test..
5082         dd if=/dev/zero of=$file bs=1024 count=100
5083         BEFOREWRITES=`count_ost_writes`
5084         $TRUNCATE $file $offset
5085         cancel_lru_locks $OSC
5086         AFTERWRITES=`count_ost_writes`
5087         start_writeback
5088 }
5089
5090 test_42c() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092
5093         trunc_test 42c 1024
5094         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5095                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5096         rm $file
5097 }
5098 run_test 42c "test partial truncate of file with cached dirty data"
5099
5100 test_42d() {
5101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5102
5103         trunc_test 42d 0
5104         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5105                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5106         rm $file
5107 }
5108 run_test 42d "test complete truncate of file with cached dirty data"
5109
5110 test_42e() { # bug22074
5111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5112
5113         local TDIR=$DIR/${tdir}e
5114         local pages=16 # hardcoded 16 pages, don't change it.
5115         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5116         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5117         local max_dirty_mb
5118         local warmup_files
5119
5120         test_mkdir $DIR/${tdir}e
5121         $LFS setstripe -c 1 $TDIR
5122         createmany -o $TDIR/f $files
5123
5124         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5125
5126         # we assume that with $OSTCOUNT files, at least one of them will
5127         # be allocated on OST0.
5128         warmup_files=$((OSTCOUNT * max_dirty_mb))
5129         createmany -o $TDIR/w $warmup_files
5130
5131         # write a large amount of data into one file and sync, to get good
5132         # avail_grant number from OST.
5133         for ((i=0; i<$warmup_files; i++)); do
5134                 idx=$($LFS getstripe -i $TDIR/w$i)
5135                 [ $idx -ne 0 ] && continue
5136                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5137                 break
5138         done
5139         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5140         sync
5141         $LCTL get_param $proc_osc0/cur_dirty_bytes
5142         $LCTL get_param $proc_osc0/cur_grant_bytes
5143
5144         # create as much dirty pages as we can while not to trigger the actual
5145         # RPCs directly. but depends on the env, VFS may trigger flush during this
5146         # period, hopefully we are good.
5147         for ((i=0; i<$warmup_files; i++)); do
5148                 idx=$($LFS getstripe -i $TDIR/w$i)
5149                 [ $idx -ne 0 ] && continue
5150                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5151         done
5152         $LCTL get_param $proc_osc0/cur_dirty_bytes
5153         $LCTL get_param $proc_osc0/cur_grant_bytes
5154
5155         # perform the real test
5156         $LCTL set_param $proc_osc0/rpc_stats 0
5157         for ((;i<$files; i++)); do
5158                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5159                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5160         done
5161         sync
5162         $LCTL get_param $proc_osc0/rpc_stats
5163
5164         local percent=0
5165         local have_ppr=false
5166         $LCTL get_param $proc_osc0/rpc_stats |
5167                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5168                         # skip lines until we are at the RPC histogram data
5169                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5170                         $have_ppr || continue
5171
5172                         # we only want the percent stat for < 16 pages
5173                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5174
5175                         percent=$((percent + WPCT))
5176                         if [[ $percent -gt 15 ]]; then
5177                                 error "less than 16-pages write RPCs" \
5178                                       "$percent% > 15%"
5179                                 break
5180                         fi
5181                 done
5182         rm -rf $TDIR
5183 }
5184 run_test 42e "verify sub-RPC writes are not done synchronously"
5185
5186 test_43A() { # was test_43
5187         test_mkdir $DIR/$tdir
5188         cp -p /bin/ls $DIR/$tdir/$tfile
5189         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5190         pid=$!
5191         # give multiop a chance to open
5192         sleep 1
5193
5194         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5195         kill -USR1 $pid
5196         # Wait for multiop to exit
5197         wait $pid
5198 }
5199 run_test 43A "execution of file opened for write should return -ETXTBSY"
5200
5201 test_43a() {
5202         test_mkdir $DIR/$tdir
5203         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5204         $DIR/$tdir/sleep 60 &
5205         SLEEP_PID=$!
5206         # Make sure exec of $tdir/sleep wins race with truncate
5207         sleep 1
5208         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5209         kill $SLEEP_PID
5210 }
5211 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5212
5213 test_43b() {
5214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5215
5216         test_mkdir $DIR/$tdir
5217         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5218         $DIR/$tdir/sleep 60 &
5219         SLEEP_PID=$!
5220         # Make sure exec of $tdir/sleep wins race with truncate
5221         sleep 1
5222         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5223         kill $SLEEP_PID
5224 }
5225 run_test 43b "truncate of file being executed should return -ETXTBSY"
5226
5227 test_43c() {
5228         local testdir="$DIR/$tdir"
5229         test_mkdir $testdir
5230         cp $SHELL $testdir/
5231         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5232                 ( cd $testdir && md5sum -c )
5233 }
5234 run_test 43c "md5sum of copy into lustre"
5235
5236 test_44A() { # was test_44
5237         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5238
5239         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5240         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5241 }
5242 run_test 44A "zero length read from a sparse stripe"
5243
5244 test_44a() {
5245         local nstripe=$($LFS getstripe -c -d $DIR)
5246         [ -z "$nstripe" ] && skip "can't get stripe info"
5247         [[ $nstripe -gt $OSTCOUNT ]] &&
5248                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5249
5250         local stride=$($LFS getstripe -S -d $DIR)
5251         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5252                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5253         fi
5254
5255         OFFSETS="0 $((stride/2)) $((stride-1))"
5256         for offset in $OFFSETS; do
5257                 for i in $(seq 0 $((nstripe-1))); do
5258                         local GLOBALOFFSETS=""
5259                         # size in Bytes
5260                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5261                         local myfn=$DIR/d44a-$size
5262                         echo "--------writing $myfn at $size"
5263                         ll_sparseness_write $myfn $size ||
5264                                 error "ll_sparseness_write"
5265                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5266                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5267                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5268
5269                         for j in $(seq 0 $((nstripe-1))); do
5270                                 # size in Bytes
5271                                 size=$((((j + $nstripe )*$stride + $offset)))
5272                                 ll_sparseness_write $myfn $size ||
5273                                         error "ll_sparseness_write"
5274                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5275                         done
5276                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5277                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5278                         rm -f $myfn
5279                 done
5280         done
5281 }
5282 run_test 44a "test sparse pwrite ==============================="
5283
5284 dirty_osc_total() {
5285         tot=0
5286         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5287                 tot=$(($tot + $d))
5288         done
5289         echo $tot
5290 }
5291 do_dirty_record() {
5292         before=`dirty_osc_total`
5293         echo executing "\"$*\""
5294         eval $*
5295         after=`dirty_osc_total`
5296         echo before $before, after $after
5297 }
5298 test_45() {
5299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5300
5301         f="$DIR/f45"
5302         # Obtain grants from OST if it supports it
5303         echo blah > ${f}_grant
5304         stop_writeback
5305         sync
5306         do_dirty_record "echo blah > $f"
5307         [[ $before -eq $after ]] && error "write wasn't cached"
5308         do_dirty_record "> $f"
5309         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5310         do_dirty_record "echo blah > $f"
5311         [[ $before -eq $after ]] && error "write wasn't cached"
5312         do_dirty_record "sync"
5313         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5314         do_dirty_record "echo blah > $f"
5315         [[ $before -eq $after ]] && error "write wasn't cached"
5316         do_dirty_record "cancel_lru_locks osc"
5317         [[ $before -gt $after ]] ||
5318                 error "lock cancellation didn't lower dirty count"
5319         start_writeback
5320 }
5321 run_test 45 "osc io page accounting ============================"
5322
5323 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5324 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5325 # objects offset and an assert hit when an rpc was built with 1023's mapped
5326 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5327 test_46() {
5328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5329
5330         f="$DIR/f46"
5331         stop_writeback
5332         sync
5333         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5334         sync
5335         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5336         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5337         sync
5338         start_writeback
5339 }
5340 run_test 46 "dirtying a previously written page ================"
5341
5342 # test_47 is removed "Device nodes check" is moved to test_28
5343
5344 test_48a() { # bug 2399
5345         [ "$mds1_FSTYPE" = "zfs" ] &&
5346         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5347                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5348
5349         test_mkdir $DIR/$tdir
5350         cd $DIR/$tdir
5351         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5352         test_mkdir $DIR/$tdir
5353         touch foo || error "'touch foo' failed after recreating cwd"
5354         test_mkdir bar
5355         touch .foo || error "'touch .foo' failed after recreating cwd"
5356         test_mkdir .bar
5357         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5358         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5359         cd . || error "'cd .' failed after recreating cwd"
5360         mkdir . && error "'mkdir .' worked after recreating cwd"
5361         rmdir . && error "'rmdir .' worked after recreating cwd"
5362         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5363         cd .. || error "'cd ..' failed after recreating cwd"
5364 }
5365 run_test 48a "Access renamed working dir (should return errors)="
5366
5367 test_48b() { # bug 2399
5368         rm -rf $DIR/$tdir
5369         test_mkdir $DIR/$tdir
5370         cd $DIR/$tdir
5371         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5372         touch foo && error "'touch foo' worked after removing cwd"
5373         mkdir foo && error "'mkdir foo' worked after removing cwd"
5374         touch .foo && error "'touch .foo' worked after removing cwd"
5375         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5376         ls . > /dev/null && error "'ls .' worked after removing cwd"
5377         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5378         mkdir . && error "'mkdir .' worked after removing cwd"
5379         rmdir . && error "'rmdir .' worked after removing cwd"
5380         ln -s . foo && error "'ln -s .' worked after removing cwd"
5381         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5382 }
5383 run_test 48b "Access removed working dir (should return errors)="
5384
5385 test_48c() { # bug 2350
5386         #lctl set_param debug=-1
5387         #set -vx
5388         rm -rf $DIR/$tdir
5389         test_mkdir -p $DIR/$tdir/dir
5390         cd $DIR/$tdir/dir
5391         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5392         $TRACE touch foo && error "touch foo worked after removing cwd"
5393         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5394         touch .foo && error "touch .foo worked after removing cwd"
5395         mkdir .foo && error "mkdir .foo worked after removing cwd"
5396         $TRACE ls . && error "'ls .' worked after removing cwd"
5397         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5398         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5399         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5400         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5401         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5402 }
5403 run_test 48c "Access removed working subdir (should return errors)"
5404
5405 test_48d() { # bug 2350
5406         #lctl set_param debug=-1
5407         #set -vx
5408         rm -rf $DIR/$tdir
5409         test_mkdir -p $DIR/$tdir/dir
5410         cd $DIR/$tdir/dir
5411         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5412         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5413         $TRACE touch foo && error "'touch foo' worked after removing parent"
5414         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5415         touch .foo && error "'touch .foo' worked after removing parent"
5416         mkdir .foo && error "mkdir .foo worked after removing parent"
5417         $TRACE ls . && error "'ls .' worked after removing parent"
5418         $TRACE ls .. && error "'ls ..' worked after removing parent"
5419         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5420         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5421         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5422         true
5423 }
5424 run_test 48d "Access removed parent subdir (should return errors)"
5425
5426 test_48e() { # bug 4134
5427         #lctl set_param debug=-1
5428         #set -vx
5429         rm -rf $DIR/$tdir
5430         test_mkdir -p $DIR/$tdir/dir
5431         cd $DIR/$tdir/dir
5432         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5433         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5434         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5435         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5436         # On a buggy kernel addition of "touch foo" after cd .. will
5437         # produce kernel oops in lookup_hash_it
5438         touch ../foo && error "'cd ..' worked after recreate parent"
5439         cd $DIR
5440         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5441 }
5442 run_test 48e "Access to recreated parent subdir (should return errors)"
5443
5444 test_48f() {
5445         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5446                 skip "need MDS >= 2.13.55"
5447         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5448         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5449                 skip "needs different host for mdt1 mdt2"
5450         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5451
5452         $LFS mkdir -i0 $DIR/$tdir
5453         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5454
5455         for d in sub1 sub2 sub3; do
5456                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5457                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5458                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5459         done
5460
5461         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5462 }
5463 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5464
5465 test_49() { # LU-1030
5466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5467         remote_ost_nodsh && skip "remote OST with nodsh"
5468
5469         # get ost1 size - $FSNAME-OST0000
5470         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5471                 awk '{ print $4 }')
5472         # write 800M at maximum
5473         [[ $ost1_size -lt 2 ]] && ost1_size=2
5474         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5475
5476         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5477         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5478         local dd_pid=$!
5479
5480         # change max_pages_per_rpc while writing the file
5481         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5482         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5483         # loop until dd process exits
5484         while ps ax -opid | grep -wq $dd_pid; do
5485                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5486                 sleep $((RANDOM % 5 + 1))
5487         done
5488         # restore original max_pages_per_rpc
5489         $LCTL set_param $osc1_mppc=$orig_mppc
5490         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5491 }
5492 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5493
5494 test_50() {
5495         # bug 1485
5496         test_mkdir $DIR/$tdir
5497         cd $DIR/$tdir
5498         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5499 }
5500 run_test 50 "special situations: /proc symlinks  ==============="
5501
5502 test_51a() {    # was test_51
5503         # bug 1516 - create an empty entry right after ".." then split dir
5504         test_mkdir -c1 $DIR/$tdir
5505         touch $DIR/$tdir/foo
5506         $MCREATE $DIR/$tdir/bar
5507         rm $DIR/$tdir/foo
5508         createmany -m $DIR/$tdir/longfile 201
5509         FNUM=202
5510         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5511                 $MCREATE $DIR/$tdir/longfile$FNUM
5512                 FNUM=$(($FNUM + 1))
5513                 echo -n "+"
5514         done
5515         echo
5516         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5517 }
5518 run_test 51a "special situations: split htree with empty entry =="
5519
5520 cleanup_print_lfs_df () {
5521         trap 0
5522         $LFS df
5523         $LFS df -i
5524 }
5525
5526 test_51b() {
5527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5528
5529         local dir=$DIR/$tdir
5530         local nrdirs=$((65536 + 100))
5531
5532         # cleanup the directory
5533         rm -fr $dir
5534
5535         test_mkdir -c1 $dir
5536
5537         $LFS df
5538         $LFS df -i
5539         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5540         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5541         [[ $numfree -lt $nrdirs ]] &&
5542                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5543
5544         # need to check free space for the directories as well
5545         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5546         numfree=$(( blkfree / $(fs_inode_ksize) ))
5547         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5548
5549         trap cleanup_print_lfs_df EXIT
5550
5551         # create files
5552         createmany -d $dir/d $nrdirs || {
5553                 unlinkmany $dir/d $nrdirs
5554                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5555         }
5556
5557         # really created :
5558         nrdirs=$(ls -U $dir | wc -l)
5559
5560         # unlink all but 100 subdirectories, then check it still works
5561         local left=100
5562         local delete=$((nrdirs - left))
5563
5564         $LFS df
5565         $LFS df -i
5566
5567         # for ldiskfs the nlink count should be 1, but this is OSD specific
5568         # and so this is listed for informational purposes only
5569         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5570         unlinkmany -d $dir/d $delete ||
5571                 error "unlink of first $delete subdirs failed"
5572
5573         echo "nlink between: $(stat -c %h $dir)"
5574         local found=$(ls -U $dir | wc -l)
5575         [ $found -ne $left ] &&
5576                 error "can't find subdirs: found only $found, expected $left"
5577
5578         unlinkmany -d $dir/d $delete $left ||
5579                 error "unlink of second $left subdirs failed"
5580         # regardless of whether the backing filesystem tracks nlink accurately
5581         # or not, the nlink count shouldn't be more than "." and ".." here
5582         local after=$(stat -c %h $dir)
5583         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5584                 echo "nlink after: $after"
5585
5586         cleanup_print_lfs_df
5587 }
5588 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5589
5590 test_51d() {
5591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5592         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5593
5594         test_mkdir $DIR/$tdir
5595         createmany -o $DIR/$tdir/t- 1000
5596         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5597         for N in $(seq 0 $((OSTCOUNT - 1))); do
5598                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5599                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5600                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5601                         '($1 == '$N') { objs += 1 } \
5602                         END { printf("%0.0f", objs) }')
5603                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5604         done
5605         unlinkmany $DIR/$tdir/t- 1000
5606
5607         NLAST=0
5608         for N in $(seq 1 $((OSTCOUNT - 1))); do
5609                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5610                         error "OST $N has less objects vs OST $NLAST" \
5611                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5612                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5613                         error "OST $N has less objects vs OST $NLAST" \
5614                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5615
5616                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5617                         error "OST $N has less #0 objects vs OST $NLAST" \
5618                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5619                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5620                         error "OST $N has less #0 objects vs OST $NLAST" \
5621                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5622                 NLAST=$N
5623         done
5624         rm -f $TMP/$tfile
5625 }
5626 run_test 51d "check object distribution"
5627
5628 test_51e() {
5629         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5630                 skip_env "ldiskfs only test"
5631         fi
5632
5633         test_mkdir -c1 $DIR/$tdir
5634         test_mkdir -c1 $DIR/$tdir/d0
5635
5636         touch $DIR/$tdir/d0/foo
5637         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5638                 error "file exceed 65000 nlink limit!"
5639         unlinkmany $DIR/$tdir/d0/f- 65001
5640         return 0
5641 }
5642 run_test 51e "check file nlink limit"
5643
5644 test_51f() {
5645         test_mkdir $DIR/$tdir
5646
5647         local max=100000
5648         local ulimit_old=$(ulimit -n)
5649         local spare=20 # number of spare fd's for scripts/libraries, etc.
5650         local mdt=$($LFS getstripe -m $DIR/$tdir)
5651         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5652
5653         echo "MDT$mdt numfree=$numfree, max=$max"
5654         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5655         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5656                 while ! ulimit -n $((numfree + spare)); do
5657                         numfree=$((numfree * 3 / 4))
5658                 done
5659                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5660         else
5661                 echo "left ulimit at $ulimit_old"
5662         fi
5663
5664         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5665                 unlinkmany $DIR/$tdir/f $numfree
5666                 error "create+open $numfree files in $DIR/$tdir failed"
5667         }
5668         ulimit -n $ulimit_old
5669
5670         # if createmany exits at 120s there will be fewer than $numfree files
5671         unlinkmany $DIR/$tdir/f $numfree || true
5672 }
5673 run_test 51f "check many open files limit"
5674
5675 test_52a() {
5676         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5677         test_mkdir $DIR/$tdir
5678         touch $DIR/$tdir/foo
5679         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5680         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5681         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5682         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5683         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5684                                         error "link worked"
5685         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5686         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5687         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5688                                                      error "lsattr"
5689         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5690         cp -r $DIR/$tdir $TMP/
5691         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5692 }
5693 run_test 52a "append-only flag test (should return errors)"
5694
5695 test_52b() {
5696         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5697         test_mkdir $DIR/$tdir
5698         touch $DIR/$tdir/foo
5699         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5700         cat test > $DIR/$tdir/foo && error "cat test worked"
5701         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5702         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5703         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5704                                         error "link worked"
5705         echo foo >> $DIR/$tdir/foo && error "echo worked"
5706         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5707         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5708         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5709         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5710                                                         error "lsattr"
5711         chattr -i $DIR/$tdir/foo || error "chattr failed"
5712
5713         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5714 }
5715 run_test 52b "immutable flag test (should return errors) ======="
5716
5717 test_53() {
5718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5719         remote_mds_nodsh && skip "remote MDS with nodsh"
5720         remote_ost_nodsh && skip "remote OST with nodsh"
5721
5722         local param
5723         local param_seq
5724         local ostname
5725         local mds_last
5726         local mds_last_seq
5727         local ost_last
5728         local ost_last_seq
5729         local ost_last_id
5730         local ostnum
5731         local node
5732         local found=false
5733         local support_last_seq=true
5734
5735         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5736                 support_last_seq=false
5737
5738         # only test MDT0000
5739         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5740         local value
5741         for value in $(do_facet $SINGLEMDS \
5742                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5743                 param=$(echo ${value[0]} | cut -d "=" -f1)
5744                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5745
5746                 if $support_last_seq; then
5747                         param_seq=$(echo $param |
5748                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5749                         mds_last_seq=$(do_facet $SINGLEMDS \
5750                                        $LCTL get_param -n $param_seq)
5751                 fi
5752                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5753
5754                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5755                 node=$(facet_active_host ost$((ostnum+1)))
5756                 param="obdfilter.$ostname.last_id"
5757                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5758                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5759                         ost_last_id=$ost_last
5760
5761                         if $support_last_seq; then
5762                                 ost_last_id=$(echo $ost_last |
5763                                               awk -F':' '{print $2}' |
5764                                               sed -e "s/^0x//g")
5765                                 ost_last_seq=$(echo $ost_last |
5766                                                awk -F':' '{print $1}')
5767                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5768                         fi
5769
5770                         if [[ $ost_last_id != $mds_last ]]; then
5771                                 error "$ost_last_id != $mds_last"
5772                         else
5773                                 found=true
5774                                 break
5775                         fi
5776                 done
5777         done
5778         $found || error "can not match last_seq/last_id for $mdtosc"
5779         return 0
5780 }
5781 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5782
5783 test_54a() {
5784         perl -MSocket -e ';' || skip "no Socket perl module installed"
5785
5786         $SOCKETSERVER $DIR/socket ||
5787                 error "$SOCKETSERVER $DIR/socket failed: $?"
5788         $SOCKETCLIENT $DIR/socket ||
5789                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5790         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5791 }
5792 run_test 54a "unix domain socket test =========================="
5793
5794 test_54b() {
5795         f="$DIR/f54b"
5796         mknod $f c 1 3
5797         chmod 0666 $f
5798         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5799 }
5800 run_test 54b "char device works in lustre ======================"
5801
5802 find_loop_dev() {
5803         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5804         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5805         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5806
5807         for i in $(seq 3 7); do
5808                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5809                 LOOPDEV=$LOOPBASE$i
5810                 LOOPNUM=$i
5811                 break
5812         done
5813 }
5814
5815 cleanup_54c() {
5816         local rc=0
5817         loopdev="$DIR/loop54c"
5818
5819         trap 0
5820         $UMOUNT $DIR/$tdir || rc=$?
5821         losetup -d $loopdev || true
5822         losetup -d $LOOPDEV || true
5823         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5824         return $rc
5825 }
5826
5827 test_54c() {
5828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5829
5830         loopdev="$DIR/loop54c"
5831
5832         find_loop_dev
5833         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5834         trap cleanup_54c EXIT
5835         mknod $loopdev b 7 $LOOPNUM
5836         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5837         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5838         losetup $loopdev $DIR/$tfile ||
5839                 error "can't set up $loopdev for $DIR/$tfile"
5840         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5841         test_mkdir $DIR/$tdir
5842         mount -t ext2 $loopdev $DIR/$tdir ||
5843                 error "error mounting $loopdev on $DIR/$tdir"
5844         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5845                 error "dd write"
5846         df $DIR/$tdir
5847         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5848                 error "dd read"
5849         cleanup_54c
5850 }
5851 run_test 54c "block device works in lustre ====================="
5852
5853 test_54d() {
5854         f="$DIR/f54d"
5855         string="aaaaaa"
5856         mknod $f p
5857         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5858 }
5859 run_test 54d "fifo device works in lustre ======================"
5860
5861 test_54e() {
5862         f="$DIR/f54e"
5863         string="aaaaaa"
5864         cp -aL /dev/console $f
5865         echo $string > $f || error "echo $string to $f failed"
5866 }
5867 run_test 54e "console/tty device works in lustre ======================"
5868
5869 test_56a() {
5870         local numfiles=3
5871         local dir=$DIR/$tdir
5872
5873         rm -rf $dir
5874         test_mkdir -p $dir/dir
5875         for i in $(seq $numfiles); do
5876                 touch $dir/file$i
5877                 touch $dir/dir/file$i
5878         done
5879
5880         local numcomp=$($LFS getstripe --component-count $dir)
5881
5882         [[ $numcomp == 0 ]] && numcomp=1
5883
5884         # test lfs getstripe with --recursive
5885         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5886
5887         [[ $filenum -eq $((numfiles * 2)) ]] ||
5888                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5889         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5890         [[ $filenum -eq $numfiles ]] ||
5891                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5892         echo "$LFS getstripe showed obdidx or l_ost_idx"
5893
5894         # test lfs getstripe with file instead of dir
5895         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5896         [[ $filenum -eq 1 ]] ||
5897                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5898         echo "$LFS getstripe file1 passed"
5899
5900         #test lfs getstripe with --verbose
5901         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5902         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5903                 error "$LFS getstripe --verbose $dir: "\
5904                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5905         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5906                 error "$LFS getstripe $dir: showed lmm_magic"
5907
5908         #test lfs getstripe with -v prints lmm_fid
5909         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5910         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5911                 error "$LFS getstripe -v $dir: "\
5912                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5913         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5914                 error "$LFS getstripe $dir: showed lmm_fid by default"
5915         echo "$LFS getstripe --verbose passed"
5916
5917         #check for FID information
5918         local fid1=$($LFS getstripe --fid $dir/file1)
5919         local fid2=$($LFS getstripe --verbose $dir/file1 |
5920                      awk '/lmm_fid: / { print $2; exit; }')
5921         local fid3=$($LFS path2fid $dir/file1)
5922
5923         [ "$fid1" != "$fid2" ] &&
5924                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5925         [ "$fid1" != "$fid3" ] &&
5926                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5927         echo "$LFS getstripe --fid passed"
5928
5929         #test lfs getstripe with --obd
5930         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5931                 error "$LFS getstripe --obd wrong_uuid: should return error"
5932
5933         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5934
5935         local ostidx=1
5936         local obduuid=$(ostuuid_from_index $ostidx)
5937         local found=$($LFS getstripe -r --obd $obduuid $dir |
5938                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5939
5940         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5941         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5942                 ((filenum--))
5943         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5944                 ((filenum--))
5945
5946         [[ $found -eq $filenum ]] ||
5947                 error "$LFS getstripe --obd: found $found expect $filenum"
5948         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5949                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5950                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5951                 error "$LFS getstripe --obd: should not show file on other obd"
5952         echo "$LFS getstripe --obd passed"
5953 }
5954 run_test 56a "check $LFS getstripe"
5955
5956 test_56b() {
5957         local dir=$DIR/$tdir
5958         local numdirs=3
5959
5960         test_mkdir $dir
5961         for i in $(seq $numdirs); do
5962                 test_mkdir $dir/dir$i
5963         done
5964
5965         # test lfs getdirstripe default mode is non-recursion, which is
5966         # different from lfs getstripe
5967         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5968
5969         [[ $dircnt -eq 1 ]] ||
5970                 error "$LFS getdirstripe: found $dircnt, not 1"
5971         dircnt=$($LFS getdirstripe --recursive $dir |
5972                 grep -c lmv_stripe_count)
5973         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5974                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5975 }
5976 run_test 56b "check $LFS getdirstripe"
5977
5978 test_56c() {
5979         remote_ost_nodsh && skip "remote OST with nodsh"
5980
5981         local ost_idx=0
5982         local ost_name=$(ostname_from_index $ost_idx)
5983         local old_status=$(ost_dev_status $ost_idx)
5984         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5985
5986         [[ -z "$old_status" ]] ||
5987                 skip_env "OST $ost_name is in $old_status status"
5988
5989         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5990         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5991                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5992         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5993                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5994                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5995         fi
5996
5997         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5998                 error "$LFS df -v showing inactive devices"
5999         sleep_maxage
6000
6001         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6002
6003         [[ "$new_status" =~ "D" ]] ||
6004                 error "$ost_name status is '$new_status', missing 'D'"
6005         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6006                 [[ "$new_status" =~ "N" ]] ||
6007                         error "$ost_name status is '$new_status', missing 'N'"
6008         fi
6009         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6010                 [[ "$new_status" =~ "f" ]] ||
6011                         error "$ost_name status is '$new_status', missing 'f'"
6012         fi
6013
6014         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6015         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6016                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6017         [[ -z "$p" ]] && restore_lustre_params < $p || true
6018         sleep_maxage
6019
6020         new_status=$(ost_dev_status $ost_idx)
6021         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6022                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6023         # can't check 'f' as devices may actually be on flash
6024 }
6025 run_test 56c "check 'lfs df' showing device status"
6026
6027 test_56d() {
6028         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6029         local osts=$($LFS df -v $MOUNT | grep -c OST)
6030
6031         $LFS df $MOUNT
6032
6033         (( mdts == MDSCOUNT )) ||
6034                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6035         (( osts == OSTCOUNT )) ||
6036                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6037 }
6038 run_test 56d "'lfs df -v' prints only configured devices"
6039
6040 NUMFILES=3
6041 NUMDIRS=3
6042 setup_56() {
6043         local local_tdir="$1"
6044         local local_numfiles="$2"
6045         local local_numdirs="$3"
6046         local dir_params="$4"
6047         local dir_stripe_params="$5"
6048
6049         if [ ! -d "$local_tdir" ] ; then
6050                 test_mkdir -p $dir_stripe_params $local_tdir
6051                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6052                 for i in $(seq $local_numfiles) ; do
6053                         touch $local_tdir/file$i
6054                 done
6055                 for i in $(seq $local_numdirs) ; do
6056                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6057                         for j in $(seq $local_numfiles) ; do
6058                                 touch $local_tdir/dir$i/file$j
6059                         done
6060                 done
6061         fi
6062 }
6063
6064 setup_56_special() {
6065         local local_tdir=$1
6066         local local_numfiles=$2
6067         local local_numdirs=$3
6068
6069         setup_56 $local_tdir $local_numfiles $local_numdirs
6070
6071         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6072                 for i in $(seq $local_numfiles) ; do
6073                         mknod $local_tdir/loop${i}b b 7 $i
6074                         mknod $local_tdir/null${i}c c 1 3
6075                         ln -s $local_tdir/file1 $local_tdir/link${i}
6076                 done
6077                 for i in $(seq $local_numdirs) ; do
6078                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6079                         mknod $local_tdir/dir$i/null${i}c c 1 3
6080                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6081                 done
6082         fi
6083 }
6084
6085 test_56g() {
6086         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6087         local expected=$(($NUMDIRS + 2))
6088
6089         setup_56 $dir $NUMFILES $NUMDIRS
6090
6091         # test lfs find with -name
6092         for i in $(seq $NUMFILES) ; do
6093                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6094
6095                 [ $nums -eq $expected ] ||
6096                         error "lfs find -name '*$i' $dir wrong: "\
6097                               "found $nums, expected $expected"
6098         done
6099 }
6100 run_test 56g "check lfs find -name"
6101
6102 test_56h() {
6103         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6104         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6105
6106         setup_56 $dir $NUMFILES $NUMDIRS
6107
6108         # test lfs find with ! -name
6109         for i in $(seq $NUMFILES) ; do
6110                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6111
6112                 [ $nums -eq $expected ] ||
6113                         error "lfs find ! -name '*$i' $dir wrong: "\
6114                               "found $nums, expected $expected"
6115         done
6116 }
6117 run_test 56h "check lfs find ! -name"
6118
6119 test_56i() {
6120         local dir=$DIR/$tdir
6121
6122         test_mkdir $dir
6123
6124         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6125         local out=$($cmd)
6126
6127         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6128 }
6129 run_test 56i "check 'lfs find -ost UUID' skips directories"
6130
6131 test_56j() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133
6134         setup_56_special $dir $NUMFILES $NUMDIRS
6135
6136         local expected=$((NUMDIRS + 1))
6137         local cmd="$LFS find -type d $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142 }
6143 run_test 56j "check lfs find -type d"
6144
6145 test_56k() {
6146         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6147
6148         setup_56_special $dir $NUMFILES $NUMDIRS
6149
6150         local expected=$(((NUMDIRS + 1) * NUMFILES))
6151         local cmd="$LFS find -type f $dir"
6152         local nums=$($cmd | wc -l)
6153
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156 }
6157 run_test 56k "check lfs find -type f"
6158
6159 test_56l() {
6160         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6161
6162         setup_56_special $dir $NUMFILES $NUMDIRS
6163
6164         local expected=$((NUMDIRS + NUMFILES))
6165         local cmd="$LFS find -type b $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170 }
6171 run_test 56l "check lfs find -type b"
6172
6173 test_56m() {
6174         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6175
6176         setup_56_special $dir $NUMFILES $NUMDIRS
6177
6178         local expected=$((NUMDIRS + NUMFILES))
6179         local cmd="$LFS find -type c $dir"
6180         local nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183 }
6184 run_test 56m "check lfs find -type c"
6185
6186 test_56n() {
6187         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6188         setup_56_special $dir $NUMFILES $NUMDIRS
6189
6190         local expected=$((NUMDIRS + NUMFILES))
6191         local cmd="$LFS find -type l $dir"
6192         local nums=$($cmd | wc -l)
6193
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56n "check lfs find -type l"
6198
6199 test_56o() {
6200         local dir=$DIR/$tdir
6201
6202         setup_56 $dir $NUMFILES $NUMDIRS
6203         utime $dir/file1 > /dev/null || error "utime (1)"
6204         utime $dir/file2 > /dev/null || error "utime (2)"
6205         utime $dir/dir1 > /dev/null || error "utime (3)"
6206         utime $dir/dir2 > /dev/null || error "utime (4)"
6207         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6208         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6209
6210         local expected=4
6211         local nums=$($LFS find -mtime +0 $dir | wc -l)
6212
6213         [ $nums -eq $expected ] ||
6214                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6215
6216         expected=12
6217         cmd="$LFS find -mtime 0 $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221 }
6222 run_test 56o "check lfs find -mtime for old files"
6223
6224 test_56ob() {
6225         local dir=$DIR/$tdir
6226         local expected=1
6227         local count=0
6228
6229         # just to make sure there is something that won't be found
6230         test_mkdir $dir
6231         touch $dir/$tfile.now
6232
6233         for age in year week day hour min; do
6234                 count=$((count + 1))
6235
6236                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6237                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6238                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6239
6240                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6241                 local nums=$($cmd | wc -l)
6242                 [ $nums -eq $expected ] ||
6243                         error "'$cmd' wrong: found $nums, expected $expected"
6244
6245                 cmd="$LFS find $dir -atime $count${age:0:1}"
6246                 nums=$($cmd | wc -l)
6247                 [ $nums -eq $expected ] ||
6248                         error "'$cmd' wrong: found $nums, expected $expected"
6249         done
6250
6251         sleep 2
6252         cmd="$LFS find $dir -ctime +1s -type f"
6253         nums=$($cmd | wc -l)
6254         (( $nums == $count * 2 + 1)) ||
6255                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6256 }
6257 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6258
6259 test_newerXY_base() {
6260         local x=$1
6261         local y=$2
6262         local dir=$DIR/$tdir
6263         local ref
6264         local negref
6265
6266         if [ $y == "t" ]; then
6267                 if [ $x == "b" ]; then
6268                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6269                 else
6270                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6271                 fi
6272         else
6273                 ref=$DIR/$tfile.newer.$x$y
6274                 touch $ref || error "touch $ref failed"
6275         fi
6276
6277         echo "before = $ref"
6278         sleep 2
6279         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6280         sleep 2
6281         if [ $y == "t" ]; then
6282                 if [ $x == "b" ]; then
6283                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6284                 else
6285                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6286                 fi
6287         else
6288                 negref=$DIR/$tfile.negnewer.$x$y
6289                 touch $negref || error "touch $negref failed"
6290         fi
6291
6292         echo "after = $negref"
6293         local cmd="$LFS find $dir -newer$x$y $ref"
6294         local nums=$(eval $cmd | wc -l)
6295         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6296
6297         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6298                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6299
6300         cmd="$LFS find $dir ! -newer$x$y $negref"
6301         nums=$(eval $cmd | wc -l)
6302         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6303                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6304
6305         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6306         nums=$(eval $cmd | wc -l)
6307         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6308                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6309
6310         rm -rf $DIR/*
6311 }
6312
6313 test_56oc() {
6314         test_newerXY_base "a" "a"
6315         test_newerXY_base "a" "m"
6316         test_newerXY_base "a" "c"
6317         test_newerXY_base "m" "a"
6318         test_newerXY_base "m" "m"
6319         test_newerXY_base "m" "c"
6320         test_newerXY_base "c" "a"
6321         test_newerXY_base "c" "m"
6322         test_newerXY_base "c" "c"
6323
6324         [[ -n "$sles_version" ]] &&
6325                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6326
6327         test_newerXY_base "a" "t"
6328         test_newerXY_base "m" "t"
6329         test_newerXY_base "c" "t"
6330
6331         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6332            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6333                 ! btime_supported && echo "btime unsupported" && return 0
6334
6335         test_newerXY_base "b" "b"
6336         test_newerXY_base "b" "t"
6337 }
6338 run_test 56oc "check lfs find -newerXY work"
6339
6340 btime_supported() {
6341         local dir=$DIR/$tdir
6342         local rc
6343
6344         mkdir -p $dir
6345         touch $dir/$tfile
6346         $LFS find $dir -btime -1d -type f
6347         rc=$?
6348         rm -rf $dir
6349         return $rc
6350 }
6351
6352 test_56od() {
6353         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6354                 ! btime_supported && skip "btime unsupported on MDS"
6355
6356         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6357                 ! btime_supported && skip "btime unsupported on clients"
6358
6359         local dir=$DIR/$tdir
6360         local ref=$DIR/$tfile.ref
6361         local negref=$DIR/$tfile.negref
6362
6363         mkdir $dir || error "mkdir $dir failed"
6364         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6365         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6366         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6367         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6368         touch $ref || error "touch $ref failed"
6369         # sleep 3 seconds at least
6370         sleep 3
6371
6372         local before=$(do_facet mds1 date +%s)
6373         local skew=$(($(date +%s) - before + 1))
6374
6375         if (( skew < 0 && skew > -5 )); then
6376                 sleep $((0 - skew + 1))
6377                 skew=0
6378         fi
6379
6380         # Set the dir stripe params to limit files all on MDT0,
6381         # otherwise we need to calc the max clock skew between
6382         # the client and MDTs.
6383         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6384         sleep 2
6385         touch $negref || error "touch $negref failed"
6386
6387         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6388         local nums=$($cmd | wc -l)
6389         local expected=$(((NUMFILES + 1) * NUMDIRS))
6390
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6395         nums=$($cmd | wc -l)
6396         expected=$((NUMFILES + 1))
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         [ $skew -lt 0 ] && return
6401
6402         local after=$(do_facet mds1 date +%s)
6403         local age=$((after - before + 1 + skew))
6404
6405         cmd="$LFS find $dir -btime -${age}s -type f"
6406         nums=$($cmd | wc -l)
6407         expected=$(((NUMFILES + 1) * NUMDIRS))
6408
6409         echo "Clock skew between client and server: $skew, age:$age"
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412
6413         expected=$(($NUMDIRS + 1))
6414         cmd="$LFS find $dir -btime -${age}s -type d"
6415         nums=$($cmd | wc -l)
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418         rm -f $ref $negref || error "Failed to remove $ref $negref"
6419 }
6420 run_test 56od "check lfs find -btime with units"
6421
6422 test_56p() {
6423         [ $RUNAS_ID -eq $UID ] &&
6424                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6425
6426         local dir=$DIR/$tdir
6427
6428         setup_56 $dir $NUMFILES $NUMDIRS
6429         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6430
6431         local expected=$NUMFILES
6432         local cmd="$LFS find -uid $RUNAS_ID $dir"
6433         local nums=$($cmd | wc -l)
6434
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6439         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443 }
6444 run_test 56p "check lfs find -uid and ! -uid"
6445
6446 test_56q() {
6447         [ $RUNAS_ID -eq $UID ] &&
6448                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6449
6450         local dir=$DIR/$tdir
6451
6452         setup_56 $dir $NUMFILES $NUMDIRS
6453         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6454
6455         local expected=$NUMFILES
6456         local cmd="$LFS find -gid $RUNAS_GID $dir"
6457         local nums=$($cmd | wc -l)
6458
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461
6462         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6463         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6464         nums=$($cmd | wc -l)
6465         [ $nums -eq $expected ] ||
6466                 error "'$cmd' wrong: found $nums, expected $expected"
6467 }
6468 run_test 56q "check lfs find -gid and ! -gid"
6469
6470 test_56r() {
6471         local dir=$DIR/$tdir
6472
6473         setup_56 $dir $NUMFILES $NUMDIRS
6474
6475         local expected=12
6476         local cmd="$LFS find -size 0 -type f -lazy $dir"
6477         local nums=$($cmd | wc -l)
6478
6479         [ $nums -eq $expected ] ||
6480                 error "'$cmd' wrong: found $nums, expected $expected"
6481         cmd="$LFS find -size 0 -type f $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485
6486         expected=0
6487         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6488         nums=$($cmd | wc -l)
6489         [ $nums -eq $expected ] ||
6490                 error "'$cmd' wrong: found $nums, expected $expected"
6491         cmd="$LFS find ! -size 0 -type f $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495
6496         echo "test" > $dir/$tfile
6497         echo "test2" > $dir/$tfile.2 && sync
6498         expected=1
6499         cmd="$LFS find -size 5 -type f -lazy $dir"
6500         nums=$($cmd | wc -l)
6501         [ $nums -eq $expected ] ||
6502                 error "'$cmd' wrong: found $nums, expected $expected"
6503         cmd="$LFS find -size 5 -type f $dir"
6504         nums=$($cmd | wc -l)
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507
6508         expected=1
6509         cmd="$LFS find -size +5 -type f -lazy $dir"
6510         nums=$($cmd | wc -l)
6511         [ $nums -eq $expected ] ||
6512                 error "'$cmd' wrong: found $nums, expected $expected"
6513         cmd="$LFS find -size +5 -type f $dir"
6514         nums=$($cmd | wc -l)
6515         [ $nums -eq $expected ] ||
6516                 error "'$cmd' wrong: found $nums, expected $expected"
6517
6518         expected=2
6519         cmd="$LFS find -size +0 -type f -lazy $dir"
6520         nums=$($cmd | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523         cmd="$LFS find -size +0 -type f $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527
6528         expected=2
6529         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6530         nums=$($cmd | wc -l)
6531         [ $nums -eq $expected ] ||
6532                 error "'$cmd' wrong: found $nums, expected $expected"
6533         cmd="$LFS find ! -size -5 -type f $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537
6538         expected=12
6539         cmd="$LFS find -size -5 -type f -lazy $dir"
6540         nums=$($cmd | wc -l)
6541         [ $nums -eq $expected ] ||
6542                 error "'$cmd' wrong: found $nums, expected $expected"
6543         cmd="$LFS find -size -5 -type f $dir"
6544         nums=$($cmd | wc -l)
6545         [ $nums -eq $expected ] ||
6546                 error "'$cmd' wrong: found $nums, expected $expected"
6547 }
6548 run_test 56r "check lfs find -size works"
6549
6550 test_56ra_sub() {
6551         local expected=$1
6552         local glimpses=$2
6553         local cmd="$3"
6554
6555         cancel_lru_locks $OSC
6556
6557         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6558         local nums=$($cmd | wc -l)
6559
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562
6563         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6564
6565         if (( rpcs_before + glimpses != rpcs_after )); then
6566                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6567                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6568
6569                 if [[ $glimpses == 0 ]]; then
6570                         error "'$cmd' should not send glimpse RPCs to OST"
6571                 else
6572                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6573                 fi
6574         fi
6575 }
6576
6577 test_56ra() {
6578         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6579                 skip "MDS < 2.12.58 doesn't return LSOM data"
6580         local dir=$DIR/$tdir
6581         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6582
6583         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6584
6585         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6586         $LCTL set_param -n llite.*.statahead_agl=0
6587         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6588
6589         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6590         # open and close all files to ensure LSOM is updated
6591         cancel_lru_locks $OSC
6592         find $dir -type f | xargs cat > /dev/null
6593
6594         #   expect_found  glimpse_rpcs  command_to_run
6595         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6596         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6597         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6598         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6599
6600         echo "test" > $dir/$tfile
6601         echo "test2" > $dir/$tfile.2 && sync
6602         cancel_lru_locks $OSC
6603         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6604
6605         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6606         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6607         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6608         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6609
6610         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6611         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6612         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6613         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6614         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6615         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6616 }
6617 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6618
6619 test_56rb() {
6620         local dir=$DIR/$tdir
6621         local tmp=$TMP/$tfile.log
6622         local mdt_idx;
6623
6624         test_mkdir -p $dir || error "failed to mkdir $dir"
6625         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6626                 error "failed to setstripe $dir/$tfile"
6627         mdt_idx=$($LFS getdirstripe -i $dir)
6628         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6629
6630         stack_trap "rm -f $tmp" EXIT
6631         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6632         ! grep -q obd_uuid $tmp ||
6633                 error "failed to find --size +100K --ost 0 $dir"
6634         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6635         ! grep -q obd_uuid $tmp ||
6636                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6637 }
6638 run_test 56rb "check lfs find --size --ost/--mdt works"
6639
6640 test_56s() { # LU-611 #LU-9369
6641         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6642
6643         local dir=$DIR/$tdir
6644         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6645
6646         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6647         for i in $(seq $NUMDIRS); do
6648                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6649         done
6650
6651         local expected=$NUMDIRS
6652         local cmd="$LFS find -c $OSTCOUNT $dir"
6653         local nums=$($cmd | wc -l)
6654
6655         [ $nums -eq $expected ] || {
6656                 $LFS getstripe -R $dir
6657                 error "'$cmd' wrong: found $nums, expected $expected"
6658         }
6659
6660         expected=$((NUMDIRS + onestripe))
6661         cmd="$LFS find -stripe-count +0 -type f $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] || {
6664                 $LFS getstripe -R $dir
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666         }
6667
6668         expected=$onestripe
6669         cmd="$LFS find -stripe-count 1 -type f $dir"
6670         nums=$($cmd | wc -l)
6671         [ $nums -eq $expected ] || {
6672                 $LFS getstripe -R $dir
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674         }
6675
6676         cmd="$LFS find -stripe-count -2 -type f $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] || {
6679                 $LFS getstripe -R $dir
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681         }
6682
6683         expected=0
6684         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6685         nums=$($cmd | wc -l)
6686         [ $nums -eq $expected ] || {
6687                 $LFS getstripe -R $dir
6688                 error "'$cmd' wrong: found $nums, expected $expected"
6689         }
6690 }
6691 run_test 56s "check lfs find -stripe-count works"
6692
6693 test_56t() { # LU-611 #LU-9369
6694         local dir=$DIR/$tdir
6695
6696         setup_56 $dir 0 $NUMDIRS
6697         for i in $(seq $NUMDIRS); do
6698                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6699         done
6700
6701         local expected=$NUMDIRS
6702         local cmd="$LFS find -S 8M $dir"
6703         local nums=$($cmd | wc -l)
6704
6705         [ $nums -eq $expected ] || {
6706                 $LFS getstripe -R $dir
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708         }
6709         rm -rf $dir
6710
6711         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6712
6713         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6714
6715         expected=$(((NUMDIRS + 1) * NUMFILES))
6716         cmd="$LFS find -stripe-size 512k -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         cmd="$LFS find -stripe-size +320k -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6727         cmd="$LFS find -stripe-size +200k -type f $dir"
6728         nums=$($cmd | wc -l)
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731
6732         cmd="$LFS find -stripe-size -640k -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=4
6738         cmd="$LFS find -stripe-size 256k -type f $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742
6743         cmd="$LFS find -stripe-size -320k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747
6748         expected=0
6749         cmd="$LFS find -stripe-size 1024k -type f $dir"
6750         nums=$($cmd | wc -l)
6751         [ $nums -eq $expected ] ||
6752                 error "'$cmd' wrong: found $nums, expected $expected"
6753 }
6754 run_test 56t "check lfs find -stripe-size works"
6755
6756 test_56u() { # LU-611
6757         local dir=$DIR/$tdir
6758
6759         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6760
6761         if [[ $OSTCOUNT -gt 1 ]]; then
6762                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6763                 onestripe=4
6764         else
6765                 onestripe=0
6766         fi
6767
6768         local expected=$(((NUMDIRS + 1) * NUMFILES))
6769         local cmd="$LFS find -stripe-index 0 -type f $dir"
6770         local nums=$($cmd | wc -l)
6771
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         expected=$onestripe
6776         cmd="$LFS find -stripe-index 1 -type f $dir"
6777         nums=$($cmd | wc -l)
6778         [ $nums -eq $expected ] ||
6779                 error "'$cmd' wrong: found $nums, expected $expected"
6780
6781         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6782         nums=$($cmd | wc -l)
6783         [ $nums -eq $expected ] ||
6784                 error "'$cmd' wrong: found $nums, expected $expected"
6785
6786         expected=0
6787         # This should produce an error and not return any files
6788         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6789         nums=$($cmd 2>/dev/null | wc -l)
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792
6793         if [[ $OSTCOUNT -gt 1 ]]; then
6794                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6795                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6796                 nums=$($cmd | wc -l)
6797                 [ $nums -eq $expected ] ||
6798                         error "'$cmd' wrong: found $nums, expected $expected"
6799         fi
6800 }
6801 run_test 56u "check lfs find -stripe-index works"
6802
6803 test_56v() {
6804         local mdt_idx=0
6805         local dir=$DIR/$tdir
6806
6807         setup_56 $dir $NUMFILES $NUMDIRS
6808
6809         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6810         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6811
6812         for file in $($LFS find -m $UUID $dir); do
6813                 file_midx=$($LFS getstripe -m $file)
6814                 [ $file_midx -eq $mdt_idx ] ||
6815                         error "lfs find -m $UUID != getstripe -m $file_midx"
6816         done
6817 }
6818 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6819
6820 test_56w() {
6821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6823
6824         local dir=$DIR/$tdir
6825
6826         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6827
6828         local stripe_size=$($LFS getstripe -S -d $dir) ||
6829                 error "$LFS getstripe -S -d $dir failed"
6830         stripe_size=${stripe_size%% *}
6831
6832         local file_size=$((stripe_size * OSTCOUNT))
6833         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6834         local required_space=$((file_num * file_size))
6835         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6836                            head -n1)
6837         [[ $free_space -le $((required_space / 1024)) ]] &&
6838                 skip_env "need $required_space, have $free_space kbytes"
6839
6840         local dd_bs=65536
6841         local dd_count=$((file_size / dd_bs))
6842
6843         # write data into the files
6844         local i
6845         local j
6846         local file
6847
6848         for i in $(seq $NUMFILES); do
6849                 file=$dir/file$i
6850                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6851                         error "write data into $file failed"
6852         done
6853         for i in $(seq $NUMDIRS); do
6854                 for j in $(seq $NUMFILES); do
6855                         file=$dir/dir$i/file$j
6856                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6857                                 error "write data into $file failed"
6858                 done
6859         done
6860
6861         # $LFS_MIGRATE will fail if hard link migration is unsupported
6862         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6863                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6864                         error "creating links to $dir/dir1/file1 failed"
6865         fi
6866
6867         local expected=-1
6868
6869         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6870
6871         # lfs_migrate file
6872         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6873
6874         echo "$cmd"
6875         eval $cmd || error "$cmd failed"
6876
6877         check_stripe_count $dir/file1 $expected
6878
6879         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6880         then
6881                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6882                 # OST 1 if it is on OST 0. This file is small enough to
6883                 # be on only one stripe.
6884                 file=$dir/migr_1_ost
6885                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6886                         error "write data into $file failed"
6887                 local obdidx=$($LFS getstripe -i $file)
6888                 local oldmd5=$(md5sum $file)
6889                 local newobdidx=0
6890
6891                 [[ $obdidx -eq 0 ]] && newobdidx=1
6892                 cmd="$LFS migrate -i $newobdidx $file"
6893                 echo $cmd
6894                 eval $cmd || error "$cmd failed"
6895
6896                 local realobdix=$($LFS getstripe -i $file)
6897                 local newmd5=$(md5sum $file)
6898
6899                 [[ $newobdidx -ne $realobdix ]] &&
6900                         error "new OST is different (was=$obdidx, "\
6901                               "wanted=$newobdidx, got=$realobdix)"
6902                 [[ "$oldmd5" != "$newmd5" ]] &&
6903                         error "md5sum differ: $oldmd5, $newmd5"
6904         fi
6905
6906         # lfs_migrate dir
6907         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6908         echo "$cmd"
6909         eval $cmd || error "$cmd failed"
6910
6911         for j in $(seq $NUMFILES); do
6912                 check_stripe_count $dir/dir1/file$j $expected
6913         done
6914
6915         # lfs_migrate works with lfs find
6916         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6917              $LFS_MIGRATE -y -c $expected"
6918         echo "$cmd"
6919         eval $cmd || error "$cmd failed"
6920
6921         for i in $(seq 2 $NUMFILES); do
6922                 check_stripe_count $dir/file$i $expected
6923         done
6924         for i in $(seq 2 $NUMDIRS); do
6925                 for j in $(seq $NUMFILES); do
6926                 check_stripe_count $dir/dir$i/file$j $expected
6927                 done
6928         done
6929 }
6930 run_test 56w "check lfs_migrate -c stripe_count works"
6931
6932 test_56wb() {
6933         local file1=$DIR/$tdir/file1
6934         local create_pool=false
6935         local initial_pool=$($LFS getstripe -p $DIR)
6936         local pool_list=()
6937         local pool=""
6938
6939         echo -n "Creating test dir..."
6940         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6941         echo "done."
6942
6943         echo -n "Creating test file..."
6944         touch $file1 || error "cannot create file"
6945         echo "done."
6946
6947         echo -n "Detecting existing pools..."
6948         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6949
6950         if [ ${#pool_list[@]} -gt 0 ]; then
6951                 echo "${pool_list[@]}"
6952                 for thispool in "${pool_list[@]}"; do
6953                         if [[ -z "$initial_pool" ||
6954                               "$initial_pool" != "$thispool" ]]; then
6955                                 pool="$thispool"
6956                                 echo "Using existing pool '$pool'"
6957                                 break
6958                         fi
6959                 done
6960         else
6961                 echo "none detected."
6962         fi
6963         if [ -z "$pool" ]; then
6964                 pool=${POOL:-testpool}
6965                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6966                 echo -n "Creating pool '$pool'..."
6967                 create_pool=true
6968                 pool_add $pool &> /dev/null ||
6969                         error "pool_add failed"
6970                 echo "done."
6971
6972                 echo -n "Adding target to pool..."
6973                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6974                         error "pool_add_targets failed"
6975                 echo "done."
6976         fi
6977
6978         echo -n "Setting pool using -p option..."
6979         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6980                 error "migrate failed rc = $?"
6981         echo "done."
6982
6983         echo -n "Verifying test file is in pool after migrating..."
6984         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6985                 error "file was not migrated to pool $pool"
6986         echo "done."
6987
6988         echo -n "Removing test file from pool '$pool'..."
6989         # "lfs migrate $file" won't remove the file from the pool
6990         # until some striping information is changed.
6991         $LFS migrate -c 1 $file1 &> /dev/null ||
6992                 error "cannot remove from pool"
6993         [ "$($LFS getstripe -p $file1)" ] &&
6994                 error "pool still set"
6995         echo "done."
6996
6997         echo -n "Setting pool using --pool option..."
6998         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6999                 error "migrate failed rc = $?"
7000         echo "done."
7001
7002         # Clean up
7003         rm -f $file1
7004         if $create_pool; then
7005                 destroy_test_pools 2> /dev/null ||
7006                         error "destroy test pools failed"
7007         fi
7008 }
7009 run_test 56wb "check lfs_migrate pool support"
7010
7011 test_56wc() {
7012         local file1="$DIR/$tdir/file1"
7013         local parent_ssize
7014         local parent_scount
7015         local cur_ssize
7016         local cur_scount
7017         local orig_ssize
7018
7019         echo -n "Creating test dir..."
7020         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7021         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7022                 error "cannot set stripe by '-S 1M -c 1'"
7023         echo "done"
7024
7025         echo -n "Setting initial stripe for test file..."
7026         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7027                 error "cannot set stripe"
7028         cur_ssize=$($LFS getstripe -S "$file1")
7029         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7030         echo "done."
7031
7032         # File currently set to -S 512K -c 1
7033
7034         # Ensure -c and -S options are rejected when -R is set
7035         echo -n "Verifying incompatible options are detected..."
7036         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7037                 error "incompatible -c and -R options not detected"
7038         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7039                 error "incompatible -S and -R options not detected"
7040         echo "done."
7041
7042         # Ensure unrecognized options are passed through to 'lfs migrate'
7043         echo -n "Verifying -S option is passed through to lfs migrate..."
7044         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7045                 error "migration failed"
7046         cur_ssize=$($LFS getstripe -S "$file1")
7047         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7048         echo "done."
7049
7050         # File currently set to -S 1M -c 1
7051
7052         # Ensure long options are supported
7053         echo -n "Verifying long options supported..."
7054         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7055                 error "long option without argument not supported"
7056         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7057                 error "long option with argument not supported"
7058         cur_ssize=$($LFS getstripe -S "$file1")
7059         [ $cur_ssize -eq 524288 ] ||
7060                 error "migrate --stripe-size $cur_ssize != 524288"
7061         echo "done."
7062
7063         # File currently set to -S 512K -c 1
7064
7065         if [ "$OSTCOUNT" -gt 1 ]; then
7066                 echo -n "Verifying explicit stripe count can be set..."
7067                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7068                         error "migrate failed"
7069                 cur_scount=$($LFS getstripe -c "$file1")
7070                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7071                 echo "done."
7072         fi
7073
7074         # File currently set to -S 512K -c 1 or -S 512K -c 2
7075
7076         # Ensure parent striping is used if -R is set, and no stripe
7077         # count or size is specified
7078         echo -n "Setting stripe for parent directory..."
7079         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7080                 error "cannot set stripe '-S 2M -c 1'"
7081         echo "done."
7082
7083         echo -n "Verifying restripe option uses parent stripe settings..."
7084         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7085         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7086         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7087                 error "migrate failed"
7088         cur_ssize=$($LFS getstripe -S "$file1")
7089         [ $cur_ssize -eq $parent_ssize ] ||
7090                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7091         cur_scount=$($LFS getstripe -c "$file1")
7092         [ $cur_scount -eq $parent_scount ] ||
7093                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7094         echo "done."
7095
7096         # File currently set to -S 1M -c 1
7097
7098         # Ensure striping is preserved if -R is not set, and no stripe
7099         # count or size is specified
7100         echo -n "Verifying striping size preserved when not specified..."
7101         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7102         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7103                 error "cannot set stripe on parent directory"
7104         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7105                 error "migrate failed"
7106         cur_ssize=$($LFS getstripe -S "$file1")
7107         [ $cur_ssize -eq $orig_ssize ] ||
7108                 error "migrate by default $cur_ssize != $orig_ssize"
7109         echo "done."
7110
7111         # Ensure file name properly detected when final option has no argument
7112         echo -n "Verifying file name properly detected..."
7113         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7114                 error "file name interpreted as option argument"
7115         echo "done."
7116
7117         # Clean up
7118         rm -f "$file1"
7119 }
7120 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7121
7122 test_56wd() {
7123         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7124
7125         local file1=$DIR/$tdir/file1
7126
7127         echo -n "Creating test dir..."
7128         test_mkdir $DIR/$tdir || error "cannot create dir"
7129         echo "done."
7130
7131         echo -n "Creating test file..."
7132         touch $file1
7133         echo "done."
7134
7135         # Ensure 'lfs migrate' will fail by using a non-existent option,
7136         # and make sure rsync is not called to recover
7137         echo -n "Make sure --no-rsync option works..."
7138         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7139                 grep -q 'refusing to fall back to rsync' ||
7140                 error "rsync was called with --no-rsync set"
7141         echo "done."
7142
7143         # Ensure rsync is called without trying 'lfs migrate' first
7144         echo -n "Make sure --rsync option works..."
7145         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7146                 grep -q 'falling back to rsync' &&
7147                 error "lfs migrate was called with --rsync set"
7148         echo "done."
7149
7150         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7151         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7152                 grep -q 'at the same time' ||
7153                 error "--rsync and --no-rsync accepted concurrently"
7154         echo "done."
7155
7156         # Clean up
7157         rm -f $file1
7158 }
7159 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7160
7161 test_56we() {
7162         local td=$DIR/$tdir
7163         local tf=$td/$tfile
7164
7165         test_mkdir $td || error "cannot create $td"
7166         touch $tf || error "cannot touch $tf"
7167
7168         echo -n "Make sure --non-direct|-D works..."
7169         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7170                 grep -q "lfs migrate --non-direct" ||
7171                 error "--non-direct option cannot work correctly"
7172         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7173                 grep -q "lfs migrate -D" ||
7174                 error "-D option cannot work correctly"
7175         echo "done."
7176 }
7177 run_test 56we "check lfs_migrate --non-direct|-D support"
7178
7179 test_56x() {
7180         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7181         check_swap_layouts_support
7182
7183         local dir=$DIR/$tdir
7184         local ref1=/etc/passwd
7185         local file1=$dir/file1
7186
7187         test_mkdir $dir || error "creating dir $dir"
7188         $LFS setstripe -c 2 $file1
7189         cp $ref1 $file1
7190         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7191         stripe=$($LFS getstripe -c $file1)
7192         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7193         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7194
7195         # clean up
7196         rm -f $file1
7197 }
7198 run_test 56x "lfs migration support"
7199
7200 test_56xa() {
7201         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7202         check_swap_layouts_support
7203
7204         local dir=$DIR/$tdir/$testnum
7205
7206         test_mkdir -p $dir
7207
7208         local ref1=/etc/passwd
7209         local file1=$dir/file1
7210
7211         $LFS setstripe -c 2 $file1
7212         cp $ref1 $file1
7213         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7214
7215         local stripe=$($LFS getstripe -c $file1)
7216
7217         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7218         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7219
7220         # clean up
7221         rm -f $file1
7222 }
7223 run_test 56xa "lfs migration --block support"
7224
7225 check_migrate_links() {
7226         local dir="$1"
7227         local file1="$dir/file1"
7228         local begin="$2"
7229         local count="$3"
7230         local runas="$4"
7231         local total_count=$(($begin + $count - 1))
7232         local symlink_count=10
7233         local uniq_count=10
7234
7235         if [ ! -f "$file1" ]; then
7236                 echo -n "creating initial file..."
7237                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7238                         error "cannot setstripe initial file"
7239                 echo "done"
7240
7241                 echo -n "creating symlinks..."
7242                 for s in $(seq 1 $symlink_count); do
7243                         ln -s "$file1" "$dir/slink$s" ||
7244                                 error "cannot create symlinks"
7245                 done
7246                 echo "done"
7247
7248                 echo -n "creating nonlinked files..."
7249                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7250                         error "cannot create nonlinked files"
7251                 echo "done"
7252         fi
7253
7254         # create hard links
7255         if [ ! -f "$dir/file$total_count" ]; then
7256                 echo -n "creating hard links $begin:$total_count..."
7257                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7258                         /dev/null || error "cannot create hard links"
7259                 echo "done"
7260         fi
7261
7262         echo -n "checking number of hard links listed in xattrs..."
7263         local fid=$($LFS getstripe -F "$file1")
7264         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7265
7266         echo "${#paths[*]}"
7267         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7268                         skip "hard link list has unexpected size, skipping test"
7269         fi
7270         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7271                         error "link names should exceed xattrs size"
7272         fi
7273
7274         echo -n "migrating files..."
7275         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7276         local rc=$?
7277         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7278         echo "done"
7279
7280         # make sure all links have been properly migrated
7281         echo -n "verifying files..."
7282         fid=$($LFS getstripe -F "$file1") ||
7283                 error "cannot get fid for file $file1"
7284         for i in $(seq 2 $total_count); do
7285                 local fid2=$($LFS getstripe -F $dir/file$i)
7286
7287                 [ "$fid2" == "$fid" ] ||
7288                         error "migrated hard link has mismatched FID"
7289         done
7290
7291         # make sure hard links were properly detected, and migration was
7292         # performed only once for the entire link set; nonlinked files should
7293         # also be migrated
7294         local actual=$(grep -c 'done' <<< "$migrate_out")
7295         local expected=$(($uniq_count + 1))
7296
7297         [ "$actual" -eq  "$expected" ] ||
7298                 error "hard links individually migrated ($actual != $expected)"
7299
7300         # make sure the correct number of hard links are present
7301         local hardlinks=$(stat -c '%h' "$file1")
7302
7303         [ $hardlinks -eq $total_count ] ||
7304                 error "num hard links $hardlinks != $total_count"
7305         echo "done"
7306
7307         return 0
7308 }
7309
7310 test_56xb() {
7311         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7312                 skip "Need MDS version at least 2.10.55"
7313
7314         local dir="$DIR/$tdir"
7315
7316         test_mkdir "$dir" || error "cannot create dir $dir"
7317
7318         echo "testing lfs migrate mode when all links fit within xattrs"
7319         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7320
7321         echo "testing rsync mode when all links fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7323
7324         echo "testing lfs migrate mode when all links do not fit within xattrs"
7325         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7326
7327         echo "testing rsync mode when all links do not fit within xattrs"
7328         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7329
7330         chown -R $RUNAS_ID $dir
7331         echo "testing non-root lfs migrate mode when not all links are in xattr"
7332         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7333
7334         # clean up
7335         rm -rf $dir
7336 }
7337 run_test 56xb "lfs migration hard link support"
7338
7339 test_56xc() {
7340         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7341
7342         local dir="$DIR/$tdir"
7343
7344         test_mkdir "$dir" || error "cannot create dir $dir"
7345
7346         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7347         echo -n "Setting initial stripe for 20MB test file..."
7348         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7349                 error "cannot setstripe 20MB file"
7350         echo "done"
7351         echo -n "Sizing 20MB test file..."
7352         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7353         echo "done"
7354         echo -n "Verifying small file autostripe count is 1..."
7355         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7356                 error "cannot migrate 20MB file"
7357         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7358                 error "cannot get stripe for $dir/20mb"
7359         [ $stripe_count -eq 1 ] ||
7360                 error "unexpected stripe count $stripe_count for 20MB file"
7361         rm -f "$dir/20mb"
7362         echo "done"
7363
7364         # Test 2: File is small enough to fit within the available space on
7365         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7366         # have at least an additional 1KB for each desired stripe for test 3
7367         echo -n "Setting stripe for 1GB test file..."
7368         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7369         echo "done"
7370         echo -n "Sizing 1GB test file..."
7371         # File size is 1GB + 3KB
7372         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7373         echo "done"
7374
7375         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7376         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7377         if (( avail > 524288 * OSTCOUNT )); then
7378                 echo -n "Migrating 1GB file..."
7379                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7380                         error "cannot migrate 1GB file"
7381                 echo "done"
7382                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7383                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7384                         error "cannot getstripe for 1GB file"
7385                 [ $stripe_count -eq 2 ] ||
7386                         error "unexpected stripe count $stripe_count != 2"
7387                 echo "done"
7388         fi
7389
7390         # Test 3: File is too large to fit within the available space on
7391         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7392         if [ $OSTCOUNT -ge 3 ]; then
7393                 # The required available space is calculated as
7394                 # file size (1GB + 3KB) / OST count (3).
7395                 local kb_per_ost=349526
7396
7397                 echo -n "Migrating 1GB file with limit..."
7398                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7399                         error "cannot migrate 1GB file with limit"
7400                 echo "done"
7401
7402                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7403                 echo -n "Verifying 1GB autostripe count with limited space..."
7404                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7405                         error "unexpected stripe count $stripe_count (min 3)"
7406                 echo "done"
7407         fi
7408
7409         # clean up
7410         rm -rf $dir
7411 }
7412 run_test 56xc "lfs migration autostripe"
7413
7414 test_56xd() {
7415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7416
7417         local dir=$DIR/$tdir
7418         local f_mgrt=$dir/$tfile.mgrt
7419         local f_yaml=$dir/$tfile.yaml
7420         local f_copy=$dir/$tfile.copy
7421         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7422         local layout_copy="-c 2 -S 2M -i 1"
7423         local yamlfile=$dir/yamlfile
7424         local layout_before;
7425         local layout_after;
7426
7427         test_mkdir "$dir" || error "cannot create dir $dir"
7428         $LFS setstripe $layout_yaml $f_yaml ||
7429                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7430         $LFS getstripe --yaml $f_yaml > $yamlfile
7431         $LFS setstripe $layout_copy $f_copy ||
7432                 error "cannot setstripe $f_copy with layout $layout_copy"
7433         touch $f_mgrt
7434         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7435
7436         # 1. test option --yaml
7437         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7438                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7439         layout_before=$(get_layout_param $f_yaml)
7440         layout_after=$(get_layout_param $f_mgrt)
7441         [ "$layout_after" == "$layout_before" ] ||
7442                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7443
7444         # 2. test option --copy
7445         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7446                 error "cannot migrate $f_mgrt with --copy $f_copy"
7447         layout_before=$(get_layout_param $f_copy)
7448         layout_after=$(get_layout_param $f_mgrt)
7449         [ "$layout_after" == "$layout_before" ] ||
7450                 error "lfs_migrate --copy: $layout_after != $layout_before"
7451 }
7452 run_test 56xd "check lfs_migrate --yaml and --copy support"
7453
7454 test_56xe() {
7455         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7456
7457         local dir=$DIR/$tdir
7458         local f_comp=$dir/$tfile
7459         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7460         local layout_before=""
7461         local layout_after=""
7462
7463         test_mkdir "$dir" || error "cannot create dir $dir"
7464         $LFS setstripe $layout $f_comp ||
7465                 error "cannot setstripe $f_comp with layout $layout"
7466         layout_before=$(get_layout_param $f_comp)
7467         dd if=/dev/zero of=$f_comp bs=1M count=4
7468
7469         # 1. migrate a comp layout file by lfs_migrate
7470         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7471         layout_after=$(get_layout_param $f_comp)
7472         [ "$layout_before" == "$layout_after" ] ||
7473                 error "lfs_migrate: $layout_before != $layout_after"
7474
7475         # 2. migrate a comp layout file by lfs migrate
7476         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7477         layout_after=$(get_layout_param $f_comp)
7478         [ "$layout_before" == "$layout_after" ] ||
7479                 error "lfs migrate: $layout_before != $layout_after"
7480 }
7481 run_test 56xe "migrate a composite layout file"
7482
7483 test_56xf() {
7484         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7485
7486         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7487                 skip "Need server version at least 2.13.53"
7488
7489         local dir=$DIR/$tdir
7490         local f_comp=$dir/$tfile
7491         local layout="-E 1M -c1 -E -1 -c2"
7492         local fid_before=""
7493         local fid_after=""
7494
7495         test_mkdir "$dir" || error "cannot create dir $dir"
7496         $LFS setstripe $layout $f_comp ||
7497                 error "cannot setstripe $f_comp with layout $layout"
7498         fid_before=$($LFS getstripe --fid $f_comp)
7499         dd if=/dev/zero of=$f_comp bs=1M count=4
7500
7501         # 1. migrate a comp layout file to a comp layout
7502         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7503         fid_after=$($LFS getstripe --fid $f_comp)
7504         [ "$fid_before" == "$fid_after" ] ||
7505                 error "comp-to-comp migrate: $fid_before != $fid_after"
7506
7507         # 2. migrate a comp layout file to a plain layout
7508         $LFS migrate -c2 $f_comp ||
7509                 error "cannot migrate $f_comp by lfs migrate"
7510         fid_after=$($LFS getstripe --fid $f_comp)
7511         [ "$fid_before" == "$fid_after" ] ||
7512                 error "comp-to-plain migrate: $fid_before != $fid_after"
7513
7514         # 3. migrate a plain layout file to a comp layout
7515         $LFS migrate $layout $f_comp ||
7516                 error "cannot migrate $f_comp by lfs migrate"
7517         fid_after=$($LFS getstripe --fid $f_comp)
7518         [ "$fid_before" == "$fid_after" ] ||
7519                 error "plain-to-comp migrate: $fid_before != $fid_after"
7520 }
7521 run_test 56xf "FID is not lost during migration of a composite layout file"
7522
7523 test_56y() {
7524         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7525                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7526
7527         local res=""
7528         local dir=$DIR/$tdir
7529         local f1=$dir/file1
7530         local f2=$dir/file2
7531
7532         test_mkdir -p $dir || error "creating dir $dir"
7533         touch $f1 || error "creating std file $f1"
7534         $MULTIOP $f2 H2c || error "creating released file $f2"
7535
7536         # a directory can be raid0, so ask only for files
7537         res=$($LFS find $dir -L raid0 -type f | wc -l)
7538         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7539
7540         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7541         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7542
7543         # only files can be released, so no need to force file search
7544         res=$($LFS find $dir -L released)
7545         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7546
7547         res=$($LFS find $dir -type f \! -L released)
7548         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7549 }
7550 run_test 56y "lfs find -L raid0|released"
7551
7552 test_56z() { # LU-4824
7553         # This checks to make sure 'lfs find' continues after errors
7554         # There are two classes of errors that should be caught:
7555         # - If multiple paths are provided, all should be searched even if one
7556         #   errors out
7557         # - If errors are encountered during the search, it should not terminate
7558         #   early
7559         local dir=$DIR/$tdir
7560         local i
7561
7562         test_mkdir $dir
7563         for i in d{0..9}; do
7564                 test_mkdir $dir/$i
7565                 touch $dir/$i/$tfile
7566         done
7567         $LFS find $DIR/non_existent_dir $dir &&
7568                 error "$LFS find did not return an error"
7569         # Make a directory unsearchable. This should NOT be the last entry in
7570         # directory order.  Arbitrarily pick the 6th entry
7571         chmod 700 $($LFS find $dir -type d | sed '6!d')
7572
7573         $RUNAS $LFS find $DIR/non_existent $dir
7574         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7575
7576         # The user should be able to see 10 directories and 9 files
7577         (( count == 19 )) ||
7578                 error "$LFS find found $count != 19 entries after error"
7579 }
7580 run_test 56z "lfs find should continue after an error"
7581
7582 test_56aa() { # LU-5937
7583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7584
7585         local dir=$DIR/$tdir
7586
7587         mkdir $dir
7588         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7589
7590         createmany -o $dir/striped_dir/${tfile}- 1024
7591         local dirs=$($LFS find --size +8k $dir/)
7592
7593         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7594 }
7595 run_test 56aa "lfs find --size under striped dir"
7596
7597 test_56ab() { # LU-10705
7598         test_mkdir $DIR/$tdir
7599         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7600         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7601         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7602         # Flush writes to ensure valid blocks.  Need to be more thorough for
7603         # ZFS, since blocks are not allocated/returned to client immediately.
7604         sync_all_data
7605         wait_zfs_commit ost1 2
7606         cancel_lru_locks osc
7607         ls -ls $DIR/$tdir
7608
7609         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7610
7611         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7612
7613         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7614         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7615
7616         rm -f $DIR/$tdir/$tfile.[123]
7617 }
7618 run_test 56ab "lfs find --blocks"
7619
7620 test_56ba() {
7621         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7622                 skip "Need MDS version at least 2.10.50"
7623
7624         # Create composite files with one component
7625         local dir=$DIR/$tdir
7626
7627         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7628         # Create composite files with three components
7629         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7630         # Create non-composite files
7631         createmany -o $dir/${tfile}- 10
7632
7633         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7634
7635         [[ $nfiles == 10 ]] ||
7636                 error "lfs find -E 1M found $nfiles != 10 files"
7637
7638         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7639         [[ $nfiles == 25 ]] ||
7640                 error "lfs find ! -E 1M found $nfiles != 25 files"
7641
7642         # All files have a component that starts at 0
7643         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7644         [[ $nfiles == 35 ]] ||
7645                 error "lfs find --component-start 0 - $nfiles != 35 files"
7646
7647         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7648         [[ $nfiles == 15 ]] ||
7649                 error "lfs find --component-start 2M - $nfiles != 15 files"
7650
7651         # All files created here have a componenet that does not starts at 2M
7652         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7653         [[ $nfiles == 35 ]] ||
7654                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7655
7656         # Find files with a specified number of components
7657         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7658         [[ $nfiles == 15 ]] ||
7659                 error "lfs find --component-count 3 - $nfiles != 15 files"
7660
7661         # Remember non-composite files have a component count of zero
7662         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7663         [[ $nfiles == 10 ]] ||
7664                 error "lfs find --component-count 0 - $nfiles != 10 files"
7665
7666         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7667         [[ $nfiles == 20 ]] ||
7668                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7669
7670         # All files have a flag called "init"
7671         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7672         [[ $nfiles == 35 ]] ||
7673                 error "lfs find --component-flags init - $nfiles != 35 files"
7674
7675         # Multi-component files will have a component not initialized
7676         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7677         [[ $nfiles == 15 ]] ||
7678                 error "lfs find !--component-flags init - $nfiles != 15 files"
7679
7680         rm -rf $dir
7681
7682 }
7683 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7684
7685 test_56ca() {
7686         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7687                 skip "Need MDS version at least 2.10.57"
7688
7689         local td=$DIR/$tdir
7690         local tf=$td/$tfile
7691         local dir
7692         local nfiles
7693         local cmd
7694         local i
7695         local j
7696
7697         # create mirrored directories and mirrored files
7698         mkdir $td || error "mkdir $td failed"
7699         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7700         createmany -o $tf- 10 || error "create $tf- failed"
7701
7702         for i in $(seq 2); do
7703                 dir=$td/dir$i
7704                 mkdir $dir || error "mkdir $dir failed"
7705                 $LFS mirror create -N$((3 + i)) $dir ||
7706                         error "create mirrored dir $dir failed"
7707                 createmany -o $dir/$tfile- 10 ||
7708                         error "create $dir/$tfile- failed"
7709         done
7710
7711         # change the states of some mirrored files
7712         echo foo > $tf-6
7713         for i in $(seq 2); do
7714                 dir=$td/dir$i
7715                 for j in $(seq 4 9); do
7716                         echo foo > $dir/$tfile-$j
7717                 done
7718         done
7719
7720         # find mirrored files with specific mirror count
7721         cmd="$LFS find --mirror-count 3 --type f $td"
7722         nfiles=$($cmd | wc -l)
7723         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7724
7725         cmd="$LFS find ! --mirror-count 3 --type f $td"
7726         nfiles=$($cmd | wc -l)
7727         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7728
7729         cmd="$LFS find --mirror-count +2 --type f $td"
7730         nfiles=$($cmd | wc -l)
7731         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7732
7733         cmd="$LFS find --mirror-count -6 --type f $td"
7734         nfiles=$($cmd | wc -l)
7735         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7736
7737         # find mirrored files with specific file state
7738         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7739         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7740
7741         cmd="$LFS find --mirror-state=ro --type f $td"
7742         nfiles=$($cmd | wc -l)
7743         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7744
7745         cmd="$LFS find ! --mirror-state=ro --type f $td"
7746         nfiles=$($cmd | wc -l)
7747         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7748
7749         cmd="$LFS find --mirror-state=wp --type f $td"
7750         nfiles=$($cmd | wc -l)
7751         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7752
7753         cmd="$LFS find ! --mirror-state=sp --type f $td"
7754         nfiles=$($cmd | wc -l)
7755         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7756 }
7757 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7758
7759 test_57a() {
7760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7761         # note test will not do anything if MDS is not local
7762         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7763                 skip_env "ldiskfs only test"
7764         fi
7765         remote_mds_nodsh && skip "remote MDS with nodsh"
7766
7767         local MNTDEV="osd*.*MDT*.mntdev"
7768         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7769         [ -z "$DEV" ] && error "can't access $MNTDEV"
7770         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7771                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7772                         error "can't access $DEV"
7773                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7774                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7775                 rm $TMP/t57a.dump
7776         done
7777 }
7778 run_test 57a "verify MDS filesystem created with large inodes =="
7779
7780 test_57b() {
7781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7782         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7783                 skip_env "ldiskfs only test"
7784         fi
7785         remote_mds_nodsh && skip "remote MDS with nodsh"
7786
7787         local dir=$DIR/$tdir
7788         local filecount=100
7789         local file1=$dir/f1
7790         local fileN=$dir/f$filecount
7791
7792         rm -rf $dir || error "removing $dir"
7793         test_mkdir -c1 $dir
7794         local mdtidx=$($LFS getstripe -m $dir)
7795         local mdtname=MDT$(printf %04x $mdtidx)
7796         local facet=mds$((mdtidx + 1))
7797
7798         echo "mcreating $filecount files"
7799         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7800
7801         # verify that files do not have EAs yet
7802         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7803                 error "$file1 has an EA"
7804         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7805                 error "$fileN has an EA"
7806
7807         sync
7808         sleep 1
7809         df $dir  #make sure we get new statfs data
7810         local mdsfree=$(do_facet $facet \
7811                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7812         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7813         local file
7814
7815         echo "opening files to create objects/EAs"
7816         for file in $(seq -f $dir/f%g 1 $filecount); do
7817                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7818                         error "opening $file"
7819         done
7820
7821         # verify that files have EAs now
7822         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7823         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7824
7825         sleep 1  #make sure we get new statfs data
7826         df $dir
7827         local mdsfree2=$(do_facet $facet \
7828                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7829         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7830
7831         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7832                 if [ "$mdsfree" != "$mdsfree2" ]; then
7833                         error "MDC before $mdcfree != after $mdcfree2"
7834                 else
7835                         echo "MDC before $mdcfree != after $mdcfree2"
7836                         echo "unable to confirm if MDS has large inodes"
7837                 fi
7838         fi
7839         rm -rf $dir
7840 }
7841 run_test 57b "default LOV EAs are stored inside large inodes ==="
7842
7843 test_58() {
7844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7845         [ -z "$(which wiretest 2>/dev/null)" ] &&
7846                         skip_env "could not find wiretest"
7847
7848         wiretest
7849 }
7850 run_test 58 "verify cross-platform wire constants =============="
7851
7852 test_59() {
7853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7854
7855         echo "touch 130 files"
7856         createmany -o $DIR/f59- 130
7857         echo "rm 130 files"
7858         unlinkmany $DIR/f59- 130
7859         sync
7860         # wait for commitment of removal
7861         wait_delete_completed
7862 }
7863 run_test 59 "verify cancellation of llog records async ========="
7864
7865 TEST60_HEAD="test_60 run $RANDOM"
7866 test_60a() {
7867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7868         remote_mgs_nodsh && skip "remote MGS with nodsh"
7869         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7870                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7871                         skip_env "missing subtest run-llog.sh"
7872
7873         log "$TEST60_HEAD - from kernel mode"
7874         do_facet mgs "$LCTL dk > /dev/null"
7875         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7876         do_facet mgs $LCTL dk > $TMP/$tfile
7877
7878         # LU-6388: test llog_reader
7879         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7880         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7881         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7882                         skip_env "missing llog_reader"
7883         local fstype=$(facet_fstype mgs)
7884         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7885                 skip_env "Only for ldiskfs or zfs type mgs"
7886
7887         local mntpt=$(facet_mntpt mgs)
7888         local mgsdev=$(mgsdevname 1)
7889         local fid_list
7890         local fid
7891         local rec_list
7892         local rec
7893         local rec_type
7894         local obj_file
7895         local path
7896         local seq
7897         local oid
7898         local pass=true
7899
7900         #get fid and record list
7901         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7902                 tail -n 4))
7903         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7904                 tail -n 4))
7905         #remount mgs as ldiskfs or zfs type
7906         stop mgs || error "stop mgs failed"
7907         mount_fstype mgs || error "remount mgs failed"
7908         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7909                 fid=${fid_list[i]}
7910                 rec=${rec_list[i]}
7911                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7912                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7913                 oid=$((16#$oid))
7914
7915                 case $fstype in
7916                         ldiskfs )
7917                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7918                         zfs )
7919                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7920                 esac
7921                 echo "obj_file is $obj_file"
7922                 do_facet mgs $llog_reader $obj_file
7923
7924                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7925                         awk '{ print $3 }' | sed -e "s/^type=//g")
7926                 if [ $rec_type != $rec ]; then
7927                         echo "FAILED test_60a wrong record type $rec_type," \
7928                               "should be $rec"
7929                         pass=false
7930                         break
7931                 fi
7932
7933                 #check obj path if record type is LLOG_LOGID_MAGIC
7934                 if [ "$rec" == "1064553b" ]; then
7935                         path=$(do_facet mgs $llog_reader $obj_file |
7936                                 grep "path=" | awk '{ print $NF }' |
7937                                 sed -e "s/^path=//g")
7938                         if [ $obj_file != $mntpt/$path ]; then
7939                                 echo "FAILED test_60a wrong obj path" \
7940                                       "$montpt/$path, should be $obj_file"
7941                                 pass=false
7942                                 break
7943                         fi
7944                 fi
7945         done
7946         rm -f $TMP/$tfile
7947         #restart mgs before "error", otherwise it will block the next test
7948         stop mgs || error "stop mgs failed"
7949         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7950         $pass || error "test failed, see FAILED test_60a messages for specifics"
7951 }
7952 run_test 60a "llog_test run from kernel module and test llog_reader"
7953
7954 test_60b() { # bug 6411
7955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7956
7957         dmesg > $DIR/$tfile
7958         LLOG_COUNT=$(do_facet mgs dmesg |
7959                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7960                           /llog_[a-z]*.c:[0-9]/ {
7961                                 if (marker)
7962                                         from_marker++
7963                                 from_begin++
7964                           }
7965                           END {
7966                                 if (marker)
7967                                         print from_marker
7968                                 else
7969                                         print from_begin
7970                           }")
7971
7972         [[ $LLOG_COUNT -gt 120 ]] &&
7973                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7974 }
7975 run_test 60b "limit repeated messages from CERROR/CWARN"
7976
7977 test_60c() {
7978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7979
7980         echo "create 5000 files"
7981         createmany -o $DIR/f60c- 5000
7982 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7983         lctl set_param fail_loc=0x80000137
7984         unlinkmany $DIR/f60c- 5000
7985         lctl set_param fail_loc=0
7986 }
7987 run_test 60c "unlink file when mds full"
7988
7989 test_60d() {
7990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7991
7992         SAVEPRINTK=$(lctl get_param -n printk)
7993         # verify "lctl mark" is even working"
7994         MESSAGE="test message ID $RANDOM $$"
7995         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7996         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7997
7998         lctl set_param printk=0 || error "set lnet.printk failed"
7999         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8000         MESSAGE="new test message ID $RANDOM $$"
8001         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8002         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8003         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8004
8005         lctl set_param -n printk="$SAVEPRINTK"
8006 }
8007 run_test 60d "test printk console message masking"
8008
8009 test_60e() {
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011         remote_mds_nodsh && skip "remote MDS with nodsh"
8012
8013         touch $DIR/$tfile
8014 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8015         do_facet mds1 lctl set_param fail_loc=0x15b
8016         rm $DIR/$tfile
8017 }
8018 run_test 60e "no space while new llog is being created"
8019
8020 test_60g() {
8021         local pid
8022         local i
8023
8024         test_mkdir -c $MDSCOUNT $DIR/$tdir
8025
8026         (
8027                 local index=0
8028                 while true; do
8029                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8030                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8031                                 2>/dev/null
8032                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8033                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8034                         index=$((index + 1))
8035                 done
8036         ) &
8037
8038         pid=$!
8039
8040         for i in {0..100}; do
8041                 # define OBD_FAIL_OSD_TXN_START    0x19a
8042                 local index=$((i % MDSCOUNT + 1))
8043
8044                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8045                         > /dev/null
8046                 sleep 0.01
8047         done
8048
8049         kill -9 $pid
8050
8051         for i in $(seq $MDSCOUNT); do
8052                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8053         done
8054
8055         mkdir $DIR/$tdir/new || error "mkdir failed"
8056         rmdir $DIR/$tdir/new || error "rmdir failed"
8057
8058         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8059                 -t namespace
8060         for i in $(seq $MDSCOUNT); do
8061                 wait_update_facet mds$i "$LCTL get_param -n \
8062                         mdd.$(facet_svc mds$i).lfsck_namespace |
8063                         awk '/^status/ { print \\\$2 }'" "completed"
8064         done
8065
8066         ls -R $DIR/$tdir || error "ls failed"
8067         rm -rf $DIR/$tdir || error "rmdir failed"
8068 }
8069 run_test 60g "transaction abort won't cause MDT hung"
8070
8071 test_60h() {
8072         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8073                 skip "Need MDS version at least 2.12.52"
8074         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8075
8076         local f
8077
8078         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8079         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8080         for fail_loc in 0x80000188 0x80000189; do
8081                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8082                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8083                         error "mkdir $dir-$fail_loc failed"
8084                 for i in {0..10}; do
8085                         # create may fail on missing stripe
8086                         echo $i > $DIR/$tdir-$fail_loc/$i
8087                 done
8088                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8089                         error "getdirstripe $tdir-$fail_loc failed"
8090                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8091                         error "migrate $tdir-$fail_loc failed"
8092                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8093                         error "getdirstripe $tdir-$fail_loc failed"
8094                 pushd $DIR/$tdir-$fail_loc
8095                 for f in *; do
8096                         echo $f | cmp $f - || error "$f data mismatch"
8097                 done
8098                 popd
8099                 rm -rf $DIR/$tdir-$fail_loc
8100         done
8101 }
8102 run_test 60h "striped directory with missing stripes can be accessed"
8103
8104 test_61a() {
8105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8106
8107         f="$DIR/f61"
8108         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8109         cancel_lru_locks osc
8110         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8111         sync
8112 }
8113 run_test 61a "mmap() writes don't make sync hang ================"
8114
8115 test_61b() {
8116         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8117 }
8118 run_test 61b "mmap() of unstriped file is successful"
8119
8120 # bug 2330 - insufficient obd_match error checking causes LBUG
8121 test_62() {
8122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8123
8124         f="$DIR/f62"
8125         echo foo > $f
8126         cancel_lru_locks osc
8127         lctl set_param fail_loc=0x405
8128         cat $f && error "cat succeeded, expect -EIO"
8129         lctl set_param fail_loc=0
8130 }
8131 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8132 # match every page all of the time.
8133 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8134
8135 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8136 # Though this test is irrelevant anymore, it helped to reveal some
8137 # other grant bugs (LU-4482), let's keep it.
8138 test_63a() {   # was test_63
8139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8140
8141         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8142
8143         for i in `seq 10` ; do
8144                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8145                 sleep 5
8146                 kill $!
8147                 sleep 1
8148         done
8149
8150         rm -f $DIR/f63 || true
8151 }
8152 run_test 63a "Verify oig_wait interruption does not crash ======="
8153
8154 # bug 2248 - async write errors didn't return to application on sync
8155 # bug 3677 - async write errors left page locked
8156 test_63b() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         debugsave
8160         lctl set_param debug=-1
8161
8162         # ensure we have a grant to do async writes
8163         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8164         rm $DIR/$tfile
8165
8166         sync    # sync lest earlier test intercept the fail_loc
8167
8168         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8169         lctl set_param fail_loc=0x80000406
8170         $MULTIOP $DIR/$tfile Owy && \
8171                 error "sync didn't return ENOMEM"
8172         sync; sleep 2; sync     # do a real sync this time to flush page
8173         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8174                 error "locked page left in cache after async error" || true
8175         debugrestore
8176 }
8177 run_test 63b "async write errors should be returned to fsync ==="
8178
8179 test_64a () {
8180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8181
8182         lfs df $DIR
8183         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8184 }
8185 run_test 64a "verify filter grant calculations (in kernel) ====="
8186
8187 test_64b () {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8191 }
8192 run_test 64b "check out-of-space detection on client"
8193
8194 test_64c() {
8195         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8196 }
8197 run_test 64c "verify grant shrink"
8198
8199 import_param() {
8200         local tgt=$1
8201         local param=$2
8202
8203         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8204 }
8205
8206 # this does exactly what osc_request.c:osc_announce_cached() does in
8207 # order to calculate max amount of grants to ask from server
8208 want_grant() {
8209         local tgt=$1
8210
8211         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8212         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8213
8214         ((rpc_in_flight++));
8215         nrpages=$((nrpages * rpc_in_flight))
8216
8217         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8218
8219         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8220
8221         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8222         local undirty=$((nrpages * PAGE_SIZE))
8223
8224         local max_extent_pages
8225         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8226         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8227         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8228         local grant_extent_tax
8229         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8230
8231         undirty=$((undirty + nrextents * grant_extent_tax))
8232
8233         echo $undirty
8234 }
8235
8236 # this is size of unit for grant allocation. It should be equal to
8237 # what tgt_grant.c:tgt_grant_chunk() calculates
8238 grant_chunk() {
8239         local tgt=$1
8240         local max_brw_size
8241         local grant_extent_tax
8242
8243         max_brw_size=$(import_param $tgt max_brw_size)
8244
8245         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8246
8247         echo $(((max_brw_size + grant_extent_tax) * 2))
8248 }
8249
8250 test_64d() {
8251         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8252                 skip "OST < 2.10.55 doesn't limit grants enough"
8253
8254         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8255
8256         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8257                 skip "no grant_param connect flag"
8258
8259         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8260
8261         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8262         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8263
8264
8265         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8266         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8267
8268         $LFS setstripe $DIR/$tfile -i 0 -c 1
8269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8270         ddpid=$!
8271
8272         while kill -0 $ddpid; do
8273                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8274
8275                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8276                         kill $ddpid
8277                         error "cur_grant $cur_grant > $max_cur_granted"
8278                 fi
8279
8280                 sleep 1
8281         done
8282 }
8283 run_test 64d "check grant limit exceed"
8284
8285 check_grants() {
8286         local tgt=$1
8287         local expected=$2
8288         local msg=$3
8289         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8290
8291         ((cur_grants == expected)) ||
8292                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8293 }
8294
8295 round_up_p2() {
8296         echo $((($1 + $2 - 1) & ~($2 - 1)))
8297 }
8298
8299 test_64e() {
8300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8301         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8302                 skip "Need OSS version at least 2.11.56"
8303
8304         # Remount client to reset grant
8305         remount_client $MOUNT || error "failed to remount client"
8306         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8307
8308         local init_grants=$(import_param $osc_tgt initial_grant)
8309
8310         check_grants $osc_tgt $init_grants "init grants"
8311
8312         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8313         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8314         local gbs=$(import_param $osc_tgt grant_block_size)
8315
8316         # write random number of bytes from max_brw_size / 4 to max_brw_size
8317         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8318         # align for direct io
8319         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8320         # round to grant consumption unit
8321         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8322
8323         local grants=$((wb_round_up + extent_tax))
8324
8325         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8326
8327         # define OBD_FAIL_TGT_NO_GRANT 0x725
8328         # make the server not grant more back
8329         do_facet ost1 $LCTL set_param fail_loc=0x725
8330         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8331
8332         do_facet ost1 $LCTL set_param fail_loc=0
8333
8334         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8335
8336         rm -f $DIR/$tfile || error "rm failed"
8337
8338         # Remount client to reset grant
8339         remount_client $MOUNT || error "failed to remount client"
8340         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8341
8342         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8343
8344         # define OBD_FAIL_TGT_NO_GRANT 0x725
8345         # make the server not grant more back
8346         do_facet ost1 $LCTL set_param fail_loc=0x725
8347         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8348         do_facet ost1 $LCTL set_param fail_loc=0
8349
8350         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8351 }
8352 run_test 64e "check grant consumption (no grant allocation)"
8353
8354 test_64f() {
8355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8356
8357         # Remount client to reset grant
8358         remount_client $MOUNT || error "failed to remount client"
8359         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8360
8361         local init_grants=$(import_param $osc_tgt initial_grant)
8362         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8363         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8364         local gbs=$(import_param $osc_tgt grant_block_size)
8365         local chunk=$(grant_chunk $osc_tgt)
8366
8367         # write random number of bytes from max_brw_size / 4 to max_brw_size
8368         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8369         # align for direct io
8370         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8371         # round to grant consumption unit
8372         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8373
8374         local grants=$((wb_round_up + extent_tax))
8375
8376         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8377         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8378                 error "error writing to $DIR/$tfile"
8379
8380         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8381                 "direct io with grant allocation"
8382
8383         rm -f $DIR/$tfile || error "rm failed"
8384
8385         # Remount client to reset grant
8386         remount_client $MOUNT || error "failed to remount client"
8387         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8388
8389         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8390
8391         local cmd="oO_WRONLY:w${write_bytes}_yc"
8392
8393         $MULTIOP $DIR/$tfile $cmd &
8394         MULTIPID=$!
8395         sleep 1
8396
8397         check_grants $osc_tgt $((init_grants - grants)) \
8398                 "buffered io, not write rpc"
8399
8400         kill -USR1 $MULTIPID
8401         wait
8402
8403         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8404                 "buffered io, one RPC"
8405 }
8406 run_test 64f "check grant consumption (with grant allocation)"
8407
8408 # bug 1414 - set/get directories' stripe info
8409 test_65a() {
8410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8411
8412         test_mkdir $DIR/$tdir
8413         touch $DIR/$tdir/f1
8414         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8415 }
8416 run_test 65a "directory with no stripe info"
8417
8418 test_65b() {
8419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8420
8421         test_mkdir $DIR/$tdir
8422         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8423
8424         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8425                                                 error "setstripe"
8426         touch $DIR/$tdir/f2
8427         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8428 }
8429 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8430
8431 test_65c() {
8432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8433         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8434
8435         test_mkdir $DIR/$tdir
8436         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8437
8438         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8439                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8440         touch $DIR/$tdir/f3
8441         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8442 }
8443 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8444
8445 test_65d() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447
8448         test_mkdir $DIR/$tdir
8449         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8450         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8451
8452         if [[ $STRIPECOUNT -le 0 ]]; then
8453                 sc=1
8454         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8455                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8456                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8457         else
8458                 sc=$(($STRIPECOUNT - 1))
8459         fi
8460         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8461         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8462         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8463                 error "lverify failed"
8464 }
8465 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8466
8467 test_65e() {
8468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8469
8470         test_mkdir $DIR/$tdir
8471
8472         $LFS setstripe $DIR/$tdir || error "setstripe"
8473         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8474                                         error "no stripe info failed"
8475         touch $DIR/$tdir/f6
8476         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8477 }
8478 run_test 65e "directory setstripe defaults"
8479
8480 test_65f() {
8481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8482
8483         test_mkdir $DIR/${tdir}f
8484         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8485                 error "setstripe succeeded" || true
8486 }
8487 run_test 65f "dir setstripe permission (should return error) ==="
8488
8489 test_65g() {
8490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8491
8492         test_mkdir $DIR/$tdir
8493         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8494
8495         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8496                 error "setstripe -S failed"
8497         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8498         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8499                 error "delete default stripe failed"
8500 }
8501 run_test 65g "directory setstripe -d"
8502
8503 test_65h() {
8504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8505
8506         test_mkdir $DIR/$tdir
8507         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8508
8509         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8510                 error "setstripe -S failed"
8511         test_mkdir $DIR/$tdir/dd1
8512         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8513                 error "stripe info inherit failed"
8514 }
8515 run_test 65h "directory stripe info inherit ===================="
8516
8517 test_65i() {
8518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8519
8520         save_layout_restore_at_exit $MOUNT
8521
8522         # bug6367: set non-default striping on root directory
8523         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8524
8525         # bug12836: getstripe on -1 default directory striping
8526         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8527
8528         # bug12836: getstripe -v on -1 default directory striping
8529         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8530
8531         # bug12836: new find on -1 default directory striping
8532         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8533 }
8534 run_test 65i "various tests to set root directory striping"
8535
8536 test_65j() { # bug6367
8537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8538
8539         sync; sleep 1
8540
8541         # if we aren't already remounting for each test, do so for this test
8542         if [ "$I_MOUNTED" = "yes" ]; then
8543                 cleanup || error "failed to unmount"
8544                 setup
8545         fi
8546
8547         save_layout_restore_at_exit $MOUNT
8548
8549         $LFS setstripe -d $MOUNT || error "setstripe failed"
8550 }
8551 run_test 65j "set default striping on root directory (bug 6367)="
8552
8553 cleanup_65k() {
8554         rm -rf $DIR/$tdir
8555         wait_delete_completed
8556         do_facet $SINGLEMDS "lctl set_param -n \
8557                 osp.$ost*MDT0000.max_create_count=$max_count"
8558         do_facet $SINGLEMDS "lctl set_param -n \
8559                 osp.$ost*MDT0000.create_count=$count"
8560         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8561         echo $INACTIVE_OSC "is Activate"
8562
8563         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8564 }
8565
8566 test_65k() { # bug11679
8567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8568         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8569         remote_mds_nodsh && skip "remote MDS with nodsh"
8570
8571         local disable_precreate=true
8572         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8573                 disable_precreate=false
8574
8575         echo "Check OST status: "
8576         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8577                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8578
8579         for OSC in $MDS_OSCS; do
8580                 echo $OSC "is active"
8581                 do_facet $SINGLEMDS lctl --device %$OSC activate
8582         done
8583
8584         for INACTIVE_OSC in $MDS_OSCS; do
8585                 local ost=$(osc_to_ost $INACTIVE_OSC)
8586                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8587                                lov.*md*.target_obd |
8588                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8589
8590                 mkdir -p $DIR/$tdir
8591                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8592                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8593
8594                 echo "Deactivate: " $INACTIVE_OSC
8595                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8596
8597                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8598                               osp.$ost*MDT0000.create_count")
8599                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8600                                   osp.$ost*MDT0000.max_create_count")
8601                 $disable_precreate &&
8602                         do_facet $SINGLEMDS "lctl set_param -n \
8603                                 osp.$ost*MDT0000.max_create_count=0"
8604
8605                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8606                         [ -f $DIR/$tdir/$idx ] && continue
8607                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8608                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8609                                 { cleanup_65k;
8610                                   error "setstripe $idx should succeed"; }
8611                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8612                 done
8613                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8614                 rmdir $DIR/$tdir
8615
8616                 do_facet $SINGLEMDS "lctl set_param -n \
8617                         osp.$ost*MDT0000.max_create_count=$max_count"
8618                 do_facet $SINGLEMDS "lctl set_param -n \
8619                         osp.$ost*MDT0000.create_count=$count"
8620                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8621                 echo $INACTIVE_OSC "is Activate"
8622
8623                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8624         done
8625 }
8626 run_test 65k "validate manual striping works properly with deactivated OSCs"
8627
8628 test_65l() { # bug 12836
8629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8630
8631         test_mkdir -p $DIR/$tdir/test_dir
8632         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8633         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8634 }
8635 run_test 65l "lfs find on -1 stripe dir ========================"
8636
8637 test_65m() {
8638         local layout=$(save_layout $MOUNT)
8639         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8640                 restore_layout $MOUNT $layout
8641                 error "setstripe should fail by non-root users"
8642         }
8643         true
8644 }
8645 run_test 65m "normal user can't set filesystem default stripe"
8646
8647 test_65n() {
8648         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8649         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8650                 skip "Need MDS version at least 2.12.50"
8651         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8652
8653         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8654         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8655         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8656
8657         local root_layout=$(save_layout $MOUNT)
8658         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8659
8660         # new subdirectory under root directory should not inherit
8661         # the default layout from root
8662         local dir1=$MOUNT/$tdir-1
8663         mkdir $dir1 || error "mkdir $dir1 failed"
8664         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8665                 error "$dir1 shouldn't have LOV EA"
8666
8667         # delete the default layout on root directory
8668         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8669
8670         local dir2=$MOUNT/$tdir-2
8671         mkdir $dir2 || error "mkdir $dir2 failed"
8672         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8673                 error "$dir2 shouldn't have LOV EA"
8674
8675         # set a new striping pattern on root directory
8676         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8677         local new_def_stripe_size=$((def_stripe_size * 2))
8678         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8679                 error "set stripe size on $MOUNT failed"
8680
8681         # new file created in $dir2 should inherit the new stripe size from
8682         # the filesystem default
8683         local file2=$dir2/$tfile-2
8684         touch $file2 || error "touch $file2 failed"
8685
8686         local file2_stripe_size=$($LFS getstripe -S $file2)
8687         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8688         {
8689                 echo "file2_stripe_size: '$file2_stripe_size'"
8690                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8691                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8692         }
8693
8694         local dir3=$MOUNT/$tdir-3
8695         mkdir $dir3 || error "mkdir $dir3 failed"
8696         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8697         # the root layout, which is the actual default layout that will be used
8698         # when new files are created in $dir3.
8699         local dir3_layout=$(get_layout_param $dir3)
8700         local root_dir_layout=$(get_layout_param $MOUNT)
8701         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8702         {
8703                 echo "dir3_layout: '$dir3_layout'"
8704                 echo "root_dir_layout: '$root_dir_layout'"
8705                 error "$dir3 should show the default layout from $MOUNT"
8706         }
8707
8708         # set OST pool on root directory
8709         local pool=$TESTNAME
8710         pool_add $pool || error "add $pool failed"
8711         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8712                 error "add targets to $pool failed"
8713
8714         $LFS setstripe -p $pool $MOUNT ||
8715                 error "set OST pool on $MOUNT failed"
8716
8717         # new file created in $dir3 should inherit the pool from
8718         # the filesystem default
8719         local file3=$dir3/$tfile-3
8720         touch $file3 || error "touch $file3 failed"
8721
8722         local file3_pool=$($LFS getstripe -p $file3)
8723         [[ "$file3_pool" = "$pool" ]] ||
8724                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8725
8726         local dir4=$MOUNT/$tdir-4
8727         mkdir $dir4 || error "mkdir $dir4 failed"
8728         local dir4_layout=$(get_layout_param $dir4)
8729         root_dir_layout=$(get_layout_param $MOUNT)
8730         echo "$LFS getstripe -d $dir4"
8731         $LFS getstripe -d $dir4
8732         echo "$LFS getstripe -d $MOUNT"
8733         $LFS getstripe -d $MOUNT
8734         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8735         {
8736                 echo "dir4_layout: '$dir4_layout'"
8737                 echo "root_dir_layout: '$root_dir_layout'"
8738                 error "$dir4 should show the default layout from $MOUNT"
8739         }
8740
8741         # new file created in $dir4 should inherit the pool from
8742         # the filesystem default
8743         local file4=$dir4/$tfile-4
8744         touch $file4 || error "touch $file4 failed"
8745
8746         local file4_pool=$($LFS getstripe -p $file4)
8747         [[ "$file4_pool" = "$pool" ]] ||
8748                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8749
8750         # new subdirectory under non-root directory should inherit
8751         # the default layout from its parent directory
8752         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8753                 error "set directory layout on $dir4 failed"
8754
8755         local dir5=$dir4/$tdir-5
8756         mkdir $dir5 || error "mkdir $dir5 failed"
8757
8758         dir4_layout=$(get_layout_param $dir4)
8759         local dir5_layout=$(get_layout_param $dir5)
8760         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8761         {
8762                 echo "dir4_layout: '$dir4_layout'"
8763                 echo "dir5_layout: '$dir5_layout'"
8764                 error "$dir5 should inherit the default layout from $dir4"
8765         }
8766
8767         # though subdir under ROOT doesn't inherit default layout, but
8768         # its sub dir/file should be created with default layout.
8769         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8770         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8771                 skip "Need MDS version at least 2.12.59"
8772
8773         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8774         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8775         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8776
8777         if [ $default_lmv_hash == "none" ]; then
8778                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8779         else
8780                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8781                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8782         fi
8783
8784         $LFS setdirstripe -D -c 2 $MOUNT ||
8785                 error "setdirstripe -D -c 2 failed"
8786         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8787         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8788         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8789 }
8790 run_test 65n "don't inherit default layout from root for new subdirectories"
8791
8792 # bug 2543 - update blocks count on client
8793 test_66() {
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795
8796         COUNT=${COUNT:-8}
8797         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8798         sync; sync_all_data; sync; sync_all_data
8799         cancel_lru_locks osc
8800         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8801         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8802 }
8803 run_test 66 "update inode blocks count on client ==============="
8804
8805 meminfo() {
8806         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8807 }
8808
8809 swap_used() {
8810         swapon -s | awk '($1 == "'$1'") { print $4 }'
8811 }
8812
8813 # bug5265, obdfilter oa2dentry return -ENOENT
8814 # #define OBD_FAIL_SRV_ENOENT 0x217
8815 test_69() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817         remote_ost_nodsh && skip "remote OST with nodsh"
8818
8819         f="$DIR/$tfile"
8820         $LFS setstripe -c 1 -i 0 $f
8821
8822         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8823
8824         do_facet ost1 lctl set_param fail_loc=0x217
8825         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8826         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8827
8828         do_facet ost1 lctl set_param fail_loc=0
8829         $DIRECTIO write $f 0 2 || error "write error"
8830
8831         cancel_lru_locks osc
8832         $DIRECTIO read $f 0 1 || error "read error"
8833
8834         do_facet ost1 lctl set_param fail_loc=0x217
8835         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8836
8837         do_facet ost1 lctl set_param fail_loc=0
8838         rm -f $f
8839 }
8840 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8841
8842 test_71() {
8843         test_mkdir $DIR/$tdir
8844         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8845         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8846 }
8847 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8848
8849 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8851         [ "$RUNAS_ID" = "$UID" ] &&
8852                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8853         # Check that testing environment is properly set up. Skip if not
8854         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8855                 skip_env "User $RUNAS_ID does not exist - skipping"
8856
8857         touch $DIR/$tfile
8858         chmod 777 $DIR/$tfile
8859         chmod ug+s $DIR/$tfile
8860         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8861                 error "$RUNAS dd $DIR/$tfile failed"
8862         # See if we are still setuid/sgid
8863         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8864                 error "S/gid is not dropped on write"
8865         # Now test that MDS is updated too
8866         cancel_lru_locks mdc
8867         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8868                 error "S/gid is not dropped on MDS"
8869         rm -f $DIR/$tfile
8870 }
8871 run_test 72a "Test that remove suid works properly (bug5695) ===="
8872
8873 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8874         local perm
8875
8876         [ "$RUNAS_ID" = "$UID" ] &&
8877                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8878         [ "$RUNAS_ID" -eq 0 ] &&
8879                 skip_env "RUNAS_ID = 0 -- skipping"
8880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8881         # Check that testing environment is properly set up. Skip if not
8882         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8883                 skip_env "User $RUNAS_ID does not exist - skipping"
8884
8885         touch $DIR/${tfile}-f{g,u}
8886         test_mkdir $DIR/${tfile}-dg
8887         test_mkdir $DIR/${tfile}-du
8888         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8889         chmod g+s $DIR/${tfile}-{f,d}g
8890         chmod u+s $DIR/${tfile}-{f,d}u
8891         for perm in 777 2777 4777; do
8892                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8893                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8894                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8895                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8896         done
8897         true
8898 }
8899 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8900
8901 # bug 3462 - multiple simultaneous MDC requests
8902 test_73() {
8903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8904
8905         test_mkdir $DIR/d73-1
8906         test_mkdir $DIR/d73-2
8907         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8908         pid1=$!
8909
8910         lctl set_param fail_loc=0x80000129
8911         $MULTIOP $DIR/d73-1/f73-2 Oc &
8912         sleep 1
8913         lctl set_param fail_loc=0
8914
8915         $MULTIOP $DIR/d73-2/f73-3 Oc &
8916         pid3=$!
8917
8918         kill -USR1 $pid1
8919         wait $pid1 || return 1
8920
8921         sleep 25
8922
8923         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8924         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8925         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8926
8927         rm -rf $DIR/d73-*
8928 }
8929 run_test 73 "multiple MDC requests (should not deadlock)"
8930
8931 test_74a() { # bug 6149, 6184
8932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8933
8934         touch $DIR/f74a
8935         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8936         #
8937         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8938         # will spin in a tight reconnection loop
8939         $LCTL set_param fail_loc=0x8000030e
8940         # get any lock that won't be difficult - lookup works.
8941         ls $DIR/f74a
8942         $LCTL set_param fail_loc=0
8943         rm -f $DIR/f74a
8944         true
8945 }
8946 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8947
8948 test_74b() { # bug 13310
8949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8950
8951         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8952         #
8953         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8954         # will spin in a tight reconnection loop
8955         $LCTL set_param fail_loc=0x8000030e
8956         # get a "difficult" lock
8957         touch $DIR/f74b
8958         $LCTL set_param fail_loc=0
8959         rm -f $DIR/f74b
8960         true
8961 }
8962 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8963
8964 test_74c() {
8965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8966
8967         #define OBD_FAIL_LDLM_NEW_LOCK
8968         $LCTL set_param fail_loc=0x319
8969         touch $DIR/$tfile && error "touch successful"
8970         $LCTL set_param fail_loc=0
8971         true
8972 }
8973 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8974
8975 slab_lic=/sys/kernel/slab/lustre_inode_cache
8976 num_objects() {
8977         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8978         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8979                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8980 }
8981
8982 test_76a() { # Now for b=20433, added originally in b=1443
8983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8984
8985         cancel_lru_locks osc
8986         # there may be some slab objects cached per core
8987         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8988         local before=$(num_objects)
8989         local count=$((512 * cpus))
8990         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8991         local margin=$((count / 10))
8992         if [[ -f $slab_lic/aliases ]]; then
8993                 local aliases=$(cat $slab_lic/aliases)
8994                 (( aliases > 0 )) && margin=$((margin * aliases))
8995         fi
8996
8997         echo "before slab objects: $before"
8998         for i in $(seq $count); do
8999                 touch $DIR/$tfile
9000                 rm -f $DIR/$tfile
9001         done
9002         cancel_lru_locks osc
9003         local after=$(num_objects)
9004         echo "created: $count, after slab objects: $after"
9005         # shared slab counts are not very accurate, allow significant margin
9006         # the main goal is that the cache growth is not permanently > $count
9007         while (( after > before + margin )); do
9008                 sleep 1
9009                 after=$(num_objects)
9010                 wait=$((wait + 1))
9011                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9012                 if (( wait > 60 )); then
9013                         error "inode slab grew from $before+$margin to $after"
9014                 fi
9015         done
9016 }
9017 run_test 76a "confirm clients recycle inodes properly ===="
9018
9019 test_76b() {
9020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9021         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9022
9023         local count=512
9024         local before=$(num_objects)
9025
9026         for i in $(seq $count); do
9027                 mkdir $DIR/$tdir
9028                 rmdir $DIR/$tdir
9029         done
9030
9031         local after=$(num_objects)
9032         local wait=0
9033
9034         while (( after > before )); do
9035                 sleep 1
9036                 after=$(num_objects)
9037                 wait=$((wait + 1))
9038                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9039                 if (( wait > 60 )); then
9040                         error "inode slab grew from $before to $after"
9041                 fi
9042         done
9043
9044         echo "slab objects before: $before, after: $after"
9045 }
9046 run_test 76b "confirm clients recycle directory inodes properly ===="
9047
9048 export ORIG_CSUM=""
9049 set_checksums()
9050 {
9051         # Note: in sptlrpc modes which enable its own bulk checksum, the
9052         # original crc32_le bulk checksum will be automatically disabled,
9053         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9054         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9055         # In this case set_checksums() will not be no-op, because sptlrpc
9056         # bulk checksum will be enabled all through the test.
9057
9058         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9059         lctl set_param -n osc.*.checksums $1
9060         return 0
9061 }
9062
9063 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9064                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9065 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9066                              tr -d [] | head -n1)}
9067 set_checksum_type()
9068 {
9069         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9070         rc=$?
9071         log "set checksum type to $1, rc = $rc"
9072         return $rc
9073 }
9074
9075 get_osc_checksum_type()
9076 {
9077         # arugment 1: OST name, like OST0000
9078         ost=$1
9079         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9080                         sed 's/.*\[\(.*\)\].*/\1/g')
9081         rc=$?
9082         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9083         echo $checksum_type
9084 }
9085
9086 F77_TMP=$TMP/f77-temp
9087 F77SZ=8
9088 setup_f77() {
9089         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9090                 error "error writing to $F77_TMP"
9091 }
9092
9093 test_77a() { # bug 10889
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095         $GSS && skip_env "could not run with gss"
9096
9097         [ ! -f $F77_TMP ] && setup_f77
9098         set_checksums 1
9099         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9100         set_checksums 0
9101         rm -f $DIR/$tfile
9102 }
9103 run_test 77a "normal checksum read/write operation"
9104
9105 test_77b() { # bug 10889
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107         $GSS && skip_env "could not run with gss"
9108
9109         [ ! -f $F77_TMP ] && setup_f77
9110         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9111         $LCTL set_param fail_loc=0x80000409
9112         set_checksums 1
9113
9114         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9115                 error "dd error: $?"
9116         $LCTL set_param fail_loc=0
9117
9118         for algo in $CKSUM_TYPES; do
9119                 cancel_lru_locks osc
9120                 set_checksum_type $algo
9121                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9122                 $LCTL set_param fail_loc=0x80000408
9123                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9124                 $LCTL set_param fail_loc=0
9125         done
9126         set_checksums 0
9127         set_checksum_type $ORIG_CSUM_TYPE
9128         rm -f $DIR/$tfile
9129 }
9130 run_test 77b "checksum error on client write, read"
9131
9132 cleanup_77c() {
9133         trap 0
9134         set_checksums 0
9135         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9136         $check_ost &&
9137                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9138         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9139         $check_ost && [ -n "$ost_file_prefix" ] &&
9140                 do_facet ost1 rm -f ${ost_file_prefix}\*
9141 }
9142
9143 test_77c() {
9144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9145         $GSS && skip_env "could not run with gss"
9146         remote_ost_nodsh && skip "remote OST with nodsh"
9147
9148         local bad1
9149         local osc_file_prefix
9150         local osc_file
9151         local check_ost=false
9152         local ost_file_prefix
9153         local ost_file
9154         local orig_cksum
9155         local dump_cksum
9156         local fid
9157
9158         # ensure corruption will occur on first OSS/OST
9159         $LFS setstripe -i 0 $DIR/$tfile
9160
9161         [ ! -f $F77_TMP ] && setup_f77
9162         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9163                 error "dd write error: $?"
9164         fid=$($LFS path2fid $DIR/$tfile)
9165
9166         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9167         then
9168                 check_ost=true
9169                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9170                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9171         else
9172                 echo "OSS do not support bulk pages dump upon error"
9173         fi
9174
9175         osc_file_prefix=$($LCTL get_param -n debug_path)
9176         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9177
9178         trap cleanup_77c EXIT
9179
9180         set_checksums 1
9181         # enable bulk pages dump upon error on Client
9182         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9183         # enable bulk pages dump upon error on OSS
9184         $check_ost &&
9185                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9186
9187         # flush Client cache to allow next read to reach OSS
9188         cancel_lru_locks osc
9189
9190         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9191         $LCTL set_param fail_loc=0x80000408
9192         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9193         $LCTL set_param fail_loc=0
9194
9195         rm -f $DIR/$tfile
9196
9197         # check cksum dump on Client
9198         osc_file=$(ls ${osc_file_prefix}*)
9199         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9200         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9201         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9202         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9203         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9204                      cksum)
9205         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9206         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9207                 error "dump content does not match on Client"
9208
9209         $check_ost || skip "No need to check cksum dump on OSS"
9210
9211         # check cksum dump on OSS
9212         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9213         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9214         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9215         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9216         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9217                 error "dump content does not match on OSS"
9218
9219         cleanup_77c
9220 }
9221 run_test 77c "checksum error on client read with debug"
9222
9223 test_77d() { # bug 10889
9224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9225         $GSS && skip_env "could not run with gss"
9226
9227         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9228         $LCTL set_param fail_loc=0x80000409
9229         set_checksums 1
9230         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9231                 error "direct write: rc=$?"
9232         $LCTL set_param fail_loc=0
9233         set_checksums 0
9234
9235         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9236         $LCTL set_param fail_loc=0x80000408
9237         set_checksums 1
9238         cancel_lru_locks osc
9239         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9240                 error "direct read: rc=$?"
9241         $LCTL set_param fail_loc=0
9242         set_checksums 0
9243 }
9244 run_test 77d "checksum error on OST direct write, read"
9245
9246 test_77f() { # bug 10889
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248         $GSS && skip_env "could not run with gss"
9249
9250         set_checksums 1
9251         for algo in $CKSUM_TYPES; do
9252                 cancel_lru_locks osc
9253                 set_checksum_type $algo
9254                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9255                 $LCTL set_param fail_loc=0x409
9256                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9257                         error "direct write succeeded"
9258                 $LCTL set_param fail_loc=0
9259         done
9260         set_checksum_type $ORIG_CSUM_TYPE
9261         set_checksums 0
9262 }
9263 run_test 77f "repeat checksum error on write (expect error)"
9264
9265 test_77g() { # bug 10889
9266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9267         $GSS && skip_env "could not run with gss"
9268         remote_ost_nodsh && skip "remote OST with nodsh"
9269
9270         [ ! -f $F77_TMP ] && setup_f77
9271
9272         local file=$DIR/$tfile
9273         stack_trap "rm -f $file" EXIT
9274
9275         $LFS setstripe -c 1 -i 0 $file
9276         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9277         do_facet ost1 lctl set_param fail_loc=0x8000021a
9278         set_checksums 1
9279         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9280                 error "write error: rc=$?"
9281         do_facet ost1 lctl set_param fail_loc=0
9282         set_checksums 0
9283
9284         cancel_lru_locks osc
9285         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9286         do_facet ost1 lctl set_param fail_loc=0x8000021b
9287         set_checksums 1
9288         cmp $F77_TMP $file || error "file compare failed"
9289         do_facet ost1 lctl set_param fail_loc=0
9290         set_checksums 0
9291 }
9292 run_test 77g "checksum error on OST write, read"
9293
9294 test_77k() { # LU-10906
9295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9296         $GSS && skip_env "could not run with gss"
9297
9298         local cksum_param="osc.$FSNAME*.checksums"
9299         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9300         local checksum
9301         local i
9302
9303         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9304         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9305         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9306
9307         for i in 0 1; do
9308                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9309                         error "failed to set checksum=$i on MGS"
9310                 wait_update $HOSTNAME "$get_checksum" $i
9311                 #remount
9312                 echo "remount client, checksum should be $i"
9313                 remount_client $MOUNT || error "failed to remount client"
9314                 checksum=$(eval $get_checksum)
9315                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9316         done
9317         # remove persistent param to avoid races with checksum mountopt below
9318         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9319                 error "failed to delete checksum on MGS"
9320
9321         for opt in "checksum" "nochecksum"; do
9322                 #remount with mount option
9323                 echo "remount client with option $opt, checksum should be $i"
9324                 umount_client $MOUNT || error "failed to umount client"
9325                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9326                         error "failed to mount client with option '$opt'"
9327                 checksum=$(eval $get_checksum)
9328                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9329                 i=$((i - 1))
9330         done
9331
9332         remount_client $MOUNT || error "failed to remount client"
9333 }
9334 run_test 77k "enable/disable checksum correctly"
9335
9336 test_77l() {
9337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9338         $GSS && skip_env "could not run with gss"
9339
9340         set_checksums 1
9341         stack_trap "set_checksums $ORIG_CSUM" EXIT
9342         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9343
9344         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9345
9346         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9347         for algo in $CKSUM_TYPES; do
9348                 set_checksum_type $algo || error "fail to set checksum type $algo"
9349                 osc_algo=$(get_osc_checksum_type OST0000)
9350                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9351
9352                 # no locks, no reqs to let the connection idle
9353                 cancel_lru_locks osc
9354                 lru_resize_disable osc
9355                 wait_osc_import_state client ost1 IDLE
9356
9357                 # ensure ost1 is connected
9358                 stat $DIR/$tfile >/dev/null || error "can't stat"
9359                 wait_osc_import_state client ost1 FULL
9360
9361                 osc_algo=$(get_osc_checksum_type OST0000)
9362                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9363         done
9364         return 0
9365 }
9366 run_test 77l "preferred checksum type is remembered after reconnected"
9367
9368 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9369 rm -f $F77_TMP
9370 unset F77_TMP
9371
9372 cleanup_test_78() {
9373         trap 0
9374         rm -f $DIR/$tfile
9375 }
9376
9377 test_78() { # bug 10901
9378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9379         remote_ost || skip_env "local OST"
9380
9381         NSEQ=5
9382         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9383         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9384         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9385         echo "MemTotal: $MEMTOTAL"
9386
9387         # reserve 256MB of memory for the kernel and other running processes,
9388         # and then take 1/2 of the remaining memory for the read/write buffers.
9389         if [ $MEMTOTAL -gt 512 ] ;then
9390                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9391         else
9392                 # for those poor memory-starved high-end clusters...
9393                 MEMTOTAL=$((MEMTOTAL / 2))
9394         fi
9395         echo "Mem to use for directio: $MEMTOTAL"
9396
9397         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9398         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9399         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9400         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9401                 head -n1)
9402         echo "Smallest OST: $SMALLESTOST"
9403         [[ $SMALLESTOST -lt 10240 ]] &&
9404                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9405
9406         trap cleanup_test_78 EXIT
9407
9408         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9409                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9410
9411         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9412         echo "File size: $F78SIZE"
9413         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9414         for i in $(seq 1 $NSEQ); do
9415                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9416                 echo directIO rdwr round $i of $NSEQ
9417                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9418         done
9419
9420         cleanup_test_78
9421 }
9422 run_test 78 "handle large O_DIRECT writes correctly ============"
9423
9424 test_79() { # bug 12743
9425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9426
9427         wait_delete_completed
9428
9429         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9430         BKFREE=$(calc_osc_kbytes kbytesfree)
9431         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9432
9433         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9434         DFTOTAL=`echo $STRING | cut -d, -f1`
9435         DFUSED=`echo $STRING  | cut -d, -f2`
9436         DFAVAIL=`echo $STRING | cut -d, -f3`
9437         DFFREE=$(($DFTOTAL - $DFUSED))
9438
9439         ALLOWANCE=$((64 * $OSTCOUNT))
9440
9441         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9442            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9443                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9444         fi
9445         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9446            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9447                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9448         fi
9449         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9450            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9451                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9452         fi
9453 }
9454 run_test 79 "df report consistency check ======================="
9455
9456 test_80() { # bug 10718
9457         remote_ost_nodsh && skip "remote OST with nodsh"
9458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9459
9460         # relax strong synchronous semantics for slow backends like ZFS
9461         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9462                 local soc="obdfilter.*.sync_lock_cancel"
9463                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9464
9465                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9466                 if [ -z "$save" ]; then
9467                         soc="obdfilter.*.sync_on_lock_cancel"
9468                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9469                 fi
9470
9471                 if [ "$save" != "never" ]; then
9472                         local hosts=$(comma_list $(osts_nodes))
9473
9474                         do_nodes $hosts $LCTL set_param $soc=never
9475                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9476                 fi
9477         fi
9478
9479         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9480         sync; sleep 1; sync
9481         local before=$(date +%s)
9482         cancel_lru_locks osc
9483         local after=$(date +%s)
9484         local diff=$((after - before))
9485         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9486
9487         rm -f $DIR/$tfile
9488 }
9489 run_test 80 "Page eviction is equally fast at high offsets too"
9490
9491 test_81a() { # LU-456
9492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9493         remote_ost_nodsh && skip "remote OST with nodsh"
9494
9495         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9496         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9497         do_facet ost1 lctl set_param fail_loc=0x80000228
9498
9499         # write should trigger a retry and success
9500         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9501         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9502         RC=$?
9503         if [ $RC -ne 0 ] ; then
9504                 error "write should success, but failed for $RC"
9505         fi
9506 }
9507 run_test 81a "OST should retry write when get -ENOSPC ==============="
9508
9509 test_81b() { # LU-456
9510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9511         remote_ost_nodsh && skip "remote OST with nodsh"
9512
9513         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9514         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9515         do_facet ost1 lctl set_param fail_loc=0x228
9516
9517         # write should retry several times and return -ENOSPC finally
9518         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9519         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9520         RC=$?
9521         ENOSPC=28
9522         if [ $RC -ne $ENOSPC ] ; then
9523                 error "dd should fail for -ENOSPC, but succeed."
9524         fi
9525 }
9526 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9527
9528 test_99() {
9529         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9530
9531         test_mkdir $DIR/$tdir.cvsroot
9532         chown $RUNAS_ID $DIR/$tdir.cvsroot
9533
9534         cd $TMP
9535         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9536
9537         cd /etc/init.d
9538         # some versions of cvs import exit(1) when asked to import links or
9539         # files they can't read.  ignore those files.
9540         local toignore=$(find . -type l -printf '-I %f\n' -o \
9541                          ! -perm /4 -printf '-I %f\n')
9542         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9543                 $tdir.reposname vtag rtag
9544
9545         cd $DIR
9546         test_mkdir $DIR/$tdir.reposname
9547         chown $RUNAS_ID $DIR/$tdir.reposname
9548         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9549
9550         cd $DIR/$tdir.reposname
9551         $RUNAS touch foo99
9552         $RUNAS cvs add -m 'addmsg' foo99
9553         $RUNAS cvs update
9554         $RUNAS cvs commit -m 'nomsg' foo99
9555         rm -fr $DIR/$tdir.cvsroot
9556 }
9557 run_test 99 "cvs strange file/directory operations"
9558
9559 test_100() {
9560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9561         [[ "$NETTYPE" =~ tcp ]] ||
9562                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9563         remote_ost_nodsh && skip "remote OST with nodsh"
9564         remote_mds_nodsh && skip "remote MDS with nodsh"
9565         remote_servers ||
9566                 skip "useless for local single node setup"
9567
9568         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9569                 [ "$PROT" != "tcp" ] && continue
9570                 RPORT=$(echo $REMOTE | cut -d: -f2)
9571                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9572
9573                 rc=0
9574                 LPORT=`echo $LOCAL | cut -d: -f2`
9575                 if [ $LPORT -ge 1024 ]; then
9576                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9577                         netstat -tna
9578                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9579                 fi
9580         done
9581         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9582 }
9583 run_test 100 "check local port using privileged port ==========="
9584
9585 function get_named_value()
9586 {
9587     local tag
9588
9589     tag=$1
9590     while read ;do
9591         line=$REPLY
9592         case $line in
9593         $tag*)
9594             echo $line | sed "s/^$tag[ ]*//"
9595             break
9596             ;;
9597         esac
9598     done
9599 }
9600
9601 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9602                    awk '/^max_cached_mb/ { print $2 }')
9603
9604 cleanup_101a() {
9605         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9606         trap 0
9607 }
9608
9609 test_101a() {
9610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9611
9612         local s
9613         local discard
9614         local nreads=10000
9615         local cache_limit=32
9616
9617         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9618         trap cleanup_101a EXIT
9619         $LCTL set_param -n llite.*.read_ahead_stats 0
9620         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9621
9622         #
9623         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9624         #
9625         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9626         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9627
9628         discard=0
9629         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9630                 get_named_value 'read but discarded' | cut -d" " -f1); do
9631                         discard=$(($discard + $s))
9632         done
9633         cleanup_101a
9634
9635         $LCTL get_param osc.*-osc*.rpc_stats
9636         $LCTL get_param llite.*.read_ahead_stats
9637
9638         # Discard is generally zero, but sometimes a few random reads line up
9639         # and trigger larger readahead, which is wasted & leads to discards.
9640         if [[ $(($discard)) -gt $nreads ]]; then
9641                 error "too many ($discard) discarded pages"
9642         fi
9643         rm -f $DIR/$tfile || true
9644 }
9645 run_test 101a "check read-ahead for random reads"
9646
9647 setup_test101bc() {
9648         test_mkdir $DIR/$tdir
9649         local ssize=$1
9650         local FILE_LENGTH=$2
9651         STRIPE_OFFSET=0
9652
9653         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9654
9655         local list=$(comma_list $(osts_nodes))
9656         set_osd_param $list '' read_cache_enable 0
9657         set_osd_param $list '' writethrough_cache_enable 0
9658
9659         trap cleanup_test101bc EXIT
9660         # prepare the read-ahead file
9661         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9662
9663         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9664                                 count=$FILE_SIZE_MB 2> /dev/null
9665
9666 }
9667
9668 cleanup_test101bc() {
9669         trap 0
9670         rm -rf $DIR/$tdir
9671         rm -f $DIR/$tfile
9672
9673         local list=$(comma_list $(osts_nodes))
9674         set_osd_param $list '' read_cache_enable 1
9675         set_osd_param $list '' writethrough_cache_enable 1
9676 }
9677
9678 calc_total() {
9679         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9680 }
9681
9682 ra_check_101() {
9683         local READ_SIZE=$1
9684         local STRIPE_SIZE=$2
9685         local FILE_LENGTH=$3
9686         local RA_INC=1048576
9687         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9688         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9689                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9690         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9691                         get_named_value 'read but discarded' |
9692                         cut -d" " -f1 | calc_total)
9693         if [[ $DISCARD -gt $discard_limit ]]; then
9694                 $LCTL get_param llite.*.read_ahead_stats
9695                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9696         else
9697                 echo "Read-ahead success for size ${READ_SIZE}"
9698         fi
9699 }
9700
9701 test_101b() {
9702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9703         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9704
9705         local STRIPE_SIZE=1048576
9706         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9707
9708         if [ $SLOW == "yes" ]; then
9709                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9710         else
9711                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9712         fi
9713
9714         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9715
9716         # prepare the read-ahead file
9717         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9718         cancel_lru_locks osc
9719         for BIDX in 2 4 8 16 32 64 128 256
9720         do
9721                 local BSIZE=$((BIDX*4096))
9722                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9723                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9724                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9725                 $LCTL set_param -n llite.*.read_ahead_stats 0
9726                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9727                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9728                 cancel_lru_locks osc
9729                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9730         done
9731         cleanup_test101bc
9732         true
9733 }
9734 run_test 101b "check stride-io mode read-ahead ================="
9735
9736 test_101c() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738
9739         local STRIPE_SIZE=1048576
9740         local FILE_LENGTH=$((STRIPE_SIZE*100))
9741         local nreads=10000
9742         local rsize=65536
9743         local osc_rpc_stats
9744
9745         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9746
9747         cancel_lru_locks osc
9748         $LCTL set_param osc.*.rpc_stats 0
9749         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9750         $LCTL get_param osc.*.rpc_stats
9751         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9752                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9753                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9754                 local size
9755
9756                 if [ $lines -le 20 ]; then
9757                         echo "continue debug"
9758                         continue
9759                 fi
9760                 for size in 1 2 4 8; do
9761                         local rpc=$(echo "$stats" |
9762                                     awk '($1 == "'$size':") {print $2; exit; }')
9763                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9764                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9765                 done
9766                 echo "$osc_rpc_stats check passed!"
9767         done
9768         cleanup_test101bc
9769         true
9770 }
9771 run_test 101c "check stripe_size aligned read-ahead ================="
9772
9773 test_101d() {
9774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9775
9776         local file=$DIR/$tfile
9777         local sz_MB=${FILESIZE_101d:-80}
9778         local ra_MB=${READAHEAD_MB:-40}
9779
9780         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9781         [ $free_MB -lt $sz_MB ] &&
9782                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9783
9784         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9785         $LFS setstripe -c -1 $file || error "setstripe failed"
9786
9787         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9788         echo Cancel LRU locks on lustre client to flush the client cache
9789         cancel_lru_locks osc
9790
9791         echo Disable read-ahead
9792         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9793         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9794         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9795         $LCTL get_param -n llite.*.max_read_ahead_mb
9796
9797         echo "Reading the test file $file with read-ahead disabled"
9798         local sz_KB=$((sz_MB * 1024 / 4))
9799         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9800         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9801         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9802                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9803
9804         echo "Cancel LRU locks on lustre client to flush the client cache"
9805         cancel_lru_locks osc
9806         echo Enable read-ahead with ${ra_MB}MB
9807         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9808
9809         echo "Reading the test file $file with read-ahead enabled"
9810         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9811                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9812
9813         echo "read-ahead disabled time read $raOFF"
9814         echo "read-ahead enabled time read $raON"
9815
9816         rm -f $file
9817         wait_delete_completed
9818
9819         # use awk for this check instead of bash because it handles decimals
9820         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9821                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9822 }
9823 run_test 101d "file read with and without read-ahead enabled"
9824
9825 test_101e() {
9826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9827
9828         local file=$DIR/$tfile
9829         local size_KB=500  #KB
9830         local count=100
9831         local bsize=1024
9832
9833         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9834         local need_KB=$((count * size_KB))
9835         [[ $free_KB -le $need_KB ]] &&
9836                 skip_env "Need free space $need_KB, have $free_KB"
9837
9838         echo "Creating $count ${size_KB}K test files"
9839         for ((i = 0; i < $count; i++)); do
9840                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9841         done
9842
9843         echo "Cancel LRU locks on lustre client to flush the client cache"
9844         cancel_lru_locks $OSC
9845
9846         echo "Reset readahead stats"
9847         $LCTL set_param -n llite.*.read_ahead_stats 0
9848
9849         for ((i = 0; i < $count; i++)); do
9850                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9851         done
9852
9853         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9854                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9855
9856         for ((i = 0; i < $count; i++)); do
9857                 rm -rf $file.$i 2>/dev/null
9858         done
9859
9860         #10000 means 20% reads are missing in readahead
9861         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9862 }
9863 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9864
9865 test_101f() {
9866         which iozone || skip_env "no iozone installed"
9867
9868         local old_debug=$($LCTL get_param debug)
9869         old_debug=${old_debug#*=}
9870         $LCTL set_param debug="reada mmap"
9871
9872         # create a test file
9873         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9874
9875         echo Cancel LRU locks on lustre client to flush the client cache
9876         cancel_lru_locks osc
9877
9878         echo Reset readahead stats
9879         $LCTL set_param -n llite.*.read_ahead_stats 0
9880
9881         echo mmap read the file with small block size
9882         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9883                 > /dev/null 2>&1
9884
9885         echo checking missing pages
9886         $LCTL get_param llite.*.read_ahead_stats
9887         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9888                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9889
9890         $LCTL set_param debug="$old_debug"
9891         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9892         rm -f $DIR/$tfile
9893 }
9894 run_test 101f "check mmap read performance"
9895
9896 test_101g_brw_size_test() {
9897         local mb=$1
9898         local pages=$((mb * 1048576 / PAGE_SIZE))
9899         local file=$DIR/$tfile
9900
9901         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9902                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9903         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9904                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9905                         return 2
9906         done
9907
9908         stack_trap "rm -f $file" EXIT
9909         $LCTL set_param -n osc.*.rpc_stats=0
9910
9911         # 10 RPCs should be enough for the test
9912         local count=10
9913         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9914                 { error "dd write ${mb} MB blocks failed"; return 3; }
9915         cancel_lru_locks osc
9916         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9917                 { error "dd write ${mb} MB blocks failed"; return 4; }
9918
9919         # calculate number of full-sized read and write RPCs
9920         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9921                 sed -n '/pages per rpc/,/^$/p' |
9922                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9923                 END { print reads,writes }'))
9924         # allow one extra full-sized read RPC for async readahead
9925         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9926                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9927         [[ ${rpcs[1]} == $count ]] ||
9928                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9929 }
9930
9931 test_101g() {
9932         remote_ost_nodsh && skip "remote OST with nodsh"
9933
9934         local rpcs
9935         local osts=$(get_facets OST)
9936         local list=$(comma_list $(osts_nodes))
9937         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9938         local brw_size="obdfilter.*.brw_size"
9939
9940         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9941
9942         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9943
9944         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9945                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9946                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9947            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9948                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9949                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9950
9951                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9952                         suffix="M"
9953
9954                 if [[ $orig_mb -lt 16 ]]; then
9955                         save_lustre_params $osts "$brw_size" > $p
9956                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9957                                 error "set 16MB RPC size failed"
9958
9959                         echo "remount client to enable new RPC size"
9960                         remount_client $MOUNT || error "remount_client failed"
9961                 fi
9962
9963                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9964                 # should be able to set brw_size=12, but no rpc_stats for that
9965                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9966         fi
9967
9968         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9969
9970         if [[ $orig_mb -lt 16 ]]; then
9971                 restore_lustre_params < $p
9972                 remount_client $MOUNT || error "remount_client restore failed"
9973         fi
9974
9975         rm -f $p $DIR/$tfile
9976 }
9977 run_test 101g "Big bulk(4/16 MiB) readahead"
9978
9979 test_101h() {
9980         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9981
9982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9983                 error "dd 70M file failed"
9984         echo Cancel LRU locks on lustre client to flush the client cache
9985         cancel_lru_locks osc
9986
9987         echo "Reset readahead stats"
9988         $LCTL set_param -n llite.*.read_ahead_stats 0
9989
9990         echo "Read 10M of data but cross 64M bundary"
9991         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9992         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9993                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9994         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9995         rm -f $p $DIR/$tfile
9996 }
9997 run_test 101h "Readahead should cover current read window"
9998
9999 test_101i() {
10000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10001                 error "dd 10M file failed"
10002
10003         local max_per_file_mb=$($LCTL get_param -n \
10004                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10005         cancel_lru_locks osc
10006         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10007         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10008                 error "set max_read_ahead_per_file_mb to 1 failed"
10009
10010         echo "Reset readahead stats"
10011         $LCTL set_param llite.*.read_ahead_stats=0
10012
10013         dd if=$DIR/$tfile of=/dev/null bs=2M
10014
10015         $LCTL get_param llite.*.read_ahead_stats
10016         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10017                      awk '/misses/ { print $2 }')
10018         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10019         rm -f $DIR/$tfile
10020 }
10021 run_test 101i "allow current readahead to exceed reservation"
10022
10023 test_101j() {
10024         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10025                 error "setstripe $DIR/$tfile failed"
10026         local file_size=$((1048576 * 16))
10027         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10028         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10029
10030         echo Disable read-ahead
10031         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10032
10033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10034         for blk in $PAGE_SIZE 1048576 $file_size; do
10035                 cancel_lru_locks osc
10036                 echo "Reset readahead stats"
10037                 $LCTL set_param -n llite.*.read_ahead_stats=0
10038                 local count=$(($file_size / $blk))
10039                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10040                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10041                              get_named_value 'failed to fast read' |
10042                              cut -d" " -f1 | calc_total)
10043                 $LCTL get_param -n llite.*.read_ahead_stats
10044                 [ $miss -eq $count ] || error "expected $count got $miss"
10045         done
10046
10047         rm -f $p $DIR/$tfile
10048 }
10049 run_test 101j "A complete read block should be submitted when no RA"
10050
10051 setup_test102() {
10052         test_mkdir $DIR/$tdir
10053         chown $RUNAS_ID $DIR/$tdir
10054         STRIPE_SIZE=65536
10055         STRIPE_OFFSET=1
10056         STRIPE_COUNT=$OSTCOUNT
10057         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10058
10059         trap cleanup_test102 EXIT
10060         cd $DIR
10061         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10062         cd $DIR/$tdir
10063         for num in 1 2 3 4; do
10064                 for count in $(seq 1 $STRIPE_COUNT); do
10065                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10066                                 local size=`expr $STRIPE_SIZE \* $num`
10067                                 local file=file"$num-$idx-$count"
10068                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10069                         done
10070                 done
10071         done
10072
10073         cd $DIR
10074         $1 tar cf $TMP/f102.tar $tdir --xattrs
10075 }
10076
10077 cleanup_test102() {
10078         trap 0
10079         rm -f $TMP/f102.tar
10080         rm -rf $DIR/d0.sanity/d102
10081 }
10082
10083 test_102a() {
10084         [ "$UID" != 0 ] && skip "must run as root"
10085         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10086                 skip_env "must have user_xattr"
10087
10088         [ -z "$(which setfattr 2>/dev/null)" ] &&
10089                 skip_env "could not find setfattr"
10090
10091         local testfile=$DIR/$tfile
10092
10093         touch $testfile
10094         echo "set/get xattr..."
10095         setfattr -n trusted.name1 -v value1 $testfile ||
10096                 error "setfattr -n trusted.name1=value1 $testfile failed"
10097         getfattr -n trusted.name1 $testfile 2> /dev/null |
10098           grep "trusted.name1=.value1" ||
10099                 error "$testfile missing trusted.name1=value1"
10100
10101         setfattr -n user.author1 -v author1 $testfile ||
10102                 error "setfattr -n user.author1=author1 $testfile failed"
10103         getfattr -n user.author1 $testfile 2> /dev/null |
10104           grep "user.author1=.author1" ||
10105                 error "$testfile missing trusted.author1=author1"
10106
10107         echo "listxattr..."
10108         setfattr -n trusted.name2 -v value2 $testfile ||
10109                 error "$testfile unable to set trusted.name2"
10110         setfattr -n trusted.name3 -v value3 $testfile ||
10111                 error "$testfile unable to set trusted.name3"
10112         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10113             grep "trusted.name" | wc -l) -eq 3 ] ||
10114                 error "$testfile missing 3 trusted.name xattrs"
10115
10116         setfattr -n user.author2 -v author2 $testfile ||
10117                 error "$testfile unable to set user.author2"
10118         setfattr -n user.author3 -v author3 $testfile ||
10119                 error "$testfile unable to set user.author3"
10120         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10121             grep "user.author" | wc -l) -eq 3 ] ||
10122                 error "$testfile missing 3 user.author xattrs"
10123
10124         echo "remove xattr..."
10125         setfattr -x trusted.name1 $testfile ||
10126                 error "$testfile error deleting trusted.name1"
10127         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10128                 error "$testfile did not delete trusted.name1 xattr"
10129
10130         setfattr -x user.author1 $testfile ||
10131                 error "$testfile error deleting user.author1"
10132         echo "set lustre special xattr ..."
10133         $LFS setstripe -c1 $testfile
10134         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10135                 awk -F "=" '/trusted.lov/ { print $2 }' )
10136         setfattr -n "trusted.lov" -v $lovea $testfile ||
10137                 error "$testfile doesn't ignore setting trusted.lov again"
10138         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10139                 error "$testfile allow setting invalid trusted.lov"
10140         rm -f $testfile
10141 }
10142 run_test 102a "user xattr test =================================="
10143
10144 check_102b_layout() {
10145         local layout="$*"
10146         local testfile=$DIR/$tfile
10147
10148         echo "test layout '$layout'"
10149         $LFS setstripe $layout $testfile || error "setstripe failed"
10150         $LFS getstripe -y $testfile
10151
10152         echo "get/set/list trusted.lov xattr ..." # b=10930
10153         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10154         [[ "$value" =~ "trusted.lov" ]] ||
10155                 error "can't get trusted.lov from $testfile"
10156         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10157                 error "getstripe failed"
10158
10159         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10160
10161         value=$(cut -d= -f2 <<<$value)
10162         # LU-13168: truncated xattr should fail if short lov_user_md header
10163         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10164                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10165         for len in $lens; do
10166                 echo "setfattr $len $testfile.2"
10167                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10168                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10169         done
10170         local stripe_size=$($LFS getstripe -S $testfile.2)
10171         local stripe_count=$($LFS getstripe -c $testfile.2)
10172         [[ $stripe_size -eq 65536 ]] ||
10173                 error "stripe size $stripe_size != 65536"
10174         [[ $stripe_count -eq $stripe_count_orig ]] ||
10175                 error "stripe count $stripe_count != $stripe_count_orig"
10176         rm $testfile $testfile.2
10177 }
10178
10179 test_102b() {
10180         [ -z "$(which setfattr 2>/dev/null)" ] &&
10181                 skip_env "could not find setfattr"
10182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10183
10184         # check plain layout
10185         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10186
10187         # and also check composite layout
10188         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10189
10190 }
10191 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10192
10193 test_102c() {
10194         [ -z "$(which setfattr 2>/dev/null)" ] &&
10195                 skip_env "could not find setfattr"
10196         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10197
10198         # b10930: get/set/list lustre.lov xattr
10199         echo "get/set/list lustre.lov xattr ..."
10200         test_mkdir $DIR/$tdir
10201         chown $RUNAS_ID $DIR/$tdir
10202         local testfile=$DIR/$tdir/$tfile
10203         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10204                 error "setstripe failed"
10205         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10206                 error "getstripe failed"
10207         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10208         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10209
10210         local testfile2=${testfile}2
10211         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10212                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10213
10214         $RUNAS $MCREATE $testfile2
10215         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10216         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10217         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10218         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10219         [ $stripe_count -eq $STRIPECOUNT ] ||
10220                 error "stripe count $stripe_count != $STRIPECOUNT"
10221 }
10222 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10223
10224 compare_stripe_info1() {
10225         local stripe_index_all_zero=true
10226
10227         for num in 1 2 3 4; do
10228                 for count in $(seq 1 $STRIPE_COUNT); do
10229                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10230                                 local size=$((STRIPE_SIZE * num))
10231                                 local file=file"$num-$offset-$count"
10232                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10233                                 [[ $stripe_size -ne $size ]] &&
10234                                     error "$file: size $stripe_size != $size"
10235                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10236                                 # allow fewer stripes to be created, ORI-601
10237                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10238                                     error "$file: count $stripe_count != $count"
10239                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10240                                 [[ $stripe_index -ne 0 ]] &&
10241                                         stripe_index_all_zero=false
10242                         done
10243                 done
10244         done
10245         $stripe_index_all_zero &&
10246                 error "all files are being extracted starting from OST index 0"
10247         return 0
10248 }
10249
10250 have_xattrs_include() {
10251         tar --help | grep -q xattrs-include &&
10252                 echo --xattrs-include="lustre.*"
10253 }
10254
10255 test_102d() {
10256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10257         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10258
10259         XINC=$(have_xattrs_include)
10260         setup_test102
10261         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10262         cd $DIR/$tdir/$tdir
10263         compare_stripe_info1
10264 }
10265 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10266
10267 test_102f() {
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10270
10271         XINC=$(have_xattrs_include)
10272         setup_test102
10273         test_mkdir $DIR/$tdir.restore
10274         cd $DIR
10275         tar cf - --xattrs $tdir | tar xf - \
10276                 -C $DIR/$tdir.restore --xattrs $XINC
10277         cd $DIR/$tdir.restore/$tdir
10278         compare_stripe_info1
10279 }
10280 run_test 102f "tar copy files, not keep osts"
10281
10282 grow_xattr() {
10283         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10284                 skip "must have user_xattr"
10285         [ -z "$(which setfattr 2>/dev/null)" ] &&
10286                 skip_env "could not find setfattr"
10287         [ -z "$(which getfattr 2>/dev/null)" ] &&
10288                 skip_env "could not find getfattr"
10289
10290         local xsize=${1:-1024}  # in bytes
10291         local file=$DIR/$tfile
10292         local value="$(generate_string $xsize)"
10293         local xbig=trusted.big
10294         local toobig=$2
10295
10296         touch $file
10297         log "save $xbig on $file"
10298         if [ -z "$toobig" ]
10299         then
10300                 setfattr -n $xbig -v $value $file ||
10301                         error "saving $xbig on $file failed"
10302         else
10303                 setfattr -n $xbig -v $value $file &&
10304                         error "saving $xbig on $file succeeded"
10305                 return 0
10306         fi
10307
10308         local orig=$(get_xattr_value $xbig $file)
10309         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10310
10311         local xsml=trusted.sml
10312         log "save $xsml on $file"
10313         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10314
10315         local new=$(get_xattr_value $xbig $file)
10316         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10317
10318         log "grow $xsml on $file"
10319         setfattr -n $xsml -v "$value" $file ||
10320                 error "growing $xsml on $file failed"
10321
10322         new=$(get_xattr_value $xbig $file)
10323         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10324         log "$xbig still valid after growing $xsml"
10325
10326         rm -f $file
10327 }
10328
10329 test_102h() { # bug 15777
10330         grow_xattr 1024
10331 }
10332 run_test 102h "grow xattr from inside inode to external block"
10333
10334 test_102ha() {
10335         large_xattr_enabled || skip_env "ea_inode feature disabled"
10336
10337         echo "setting xattr of max xattr size: $(max_xattr_size)"
10338         grow_xattr $(max_xattr_size)
10339
10340         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10341         echo "This should fail:"
10342         grow_xattr $(($(max_xattr_size) + 10)) 1
10343 }
10344 run_test 102ha "grow xattr from inside inode to external inode"
10345
10346 test_102i() { # bug 17038
10347         [ -z "$(which getfattr 2>/dev/null)" ] &&
10348                 skip "could not find getfattr"
10349
10350         touch $DIR/$tfile
10351         ln -s $DIR/$tfile $DIR/${tfile}link
10352         getfattr -n trusted.lov $DIR/$tfile ||
10353                 error "lgetxattr on $DIR/$tfile failed"
10354         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10355                 grep -i "no such attr" ||
10356                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10357         rm -f $DIR/$tfile $DIR/${tfile}link
10358 }
10359 run_test 102i "lgetxattr test on symbolic link ============"
10360
10361 test_102j() {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10364
10365         XINC=$(have_xattrs_include)
10366         setup_test102 "$RUNAS"
10367         chown $RUNAS_ID $DIR/$tdir
10368         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10369         cd $DIR/$tdir/$tdir
10370         compare_stripe_info1 "$RUNAS"
10371 }
10372 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10373
10374 test_102k() {
10375         [ -z "$(which setfattr 2>/dev/null)" ] &&
10376                 skip "could not find setfattr"
10377
10378         touch $DIR/$tfile
10379         # b22187 just check that does not crash for regular file.
10380         setfattr -n trusted.lov $DIR/$tfile
10381         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10382         local test_kdir=$DIR/$tdir
10383         test_mkdir $test_kdir
10384         local default_size=$($LFS getstripe -S $test_kdir)
10385         local default_count=$($LFS getstripe -c $test_kdir)
10386         local default_offset=$($LFS getstripe -i $test_kdir)
10387         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10388                 error 'dir setstripe failed'
10389         setfattr -n trusted.lov $test_kdir
10390         local stripe_size=$($LFS getstripe -S $test_kdir)
10391         local stripe_count=$($LFS getstripe -c $test_kdir)
10392         local stripe_offset=$($LFS getstripe -i $test_kdir)
10393         [ $stripe_size -eq $default_size ] ||
10394                 error "stripe size $stripe_size != $default_size"
10395         [ $stripe_count -eq $default_count ] ||
10396                 error "stripe count $stripe_count != $default_count"
10397         [ $stripe_offset -eq $default_offset ] ||
10398                 error "stripe offset $stripe_offset != $default_offset"
10399         rm -rf $DIR/$tfile $test_kdir
10400 }
10401 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10402
10403 test_102l() {
10404         [ -z "$(which getfattr 2>/dev/null)" ] &&
10405                 skip "could not find getfattr"
10406
10407         # LU-532 trusted. xattr is invisible to non-root
10408         local testfile=$DIR/$tfile
10409
10410         touch $testfile
10411
10412         echo "listxattr as user..."
10413         chown $RUNAS_ID $testfile
10414         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10415             grep -q "trusted" &&
10416                 error "$testfile trusted xattrs are user visible"
10417
10418         return 0;
10419 }
10420 run_test 102l "listxattr size test =================================="
10421
10422 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10423         local path=$DIR/$tfile
10424         touch $path
10425
10426         listxattr_size_check $path || error "listattr_size_check $path failed"
10427 }
10428 run_test 102m "Ensure listxattr fails on small bufffer ========"
10429
10430 cleanup_test102
10431
10432 getxattr() { # getxattr path name
10433         # Return the base64 encoding of the value of xattr name on path.
10434         local path=$1
10435         local name=$2
10436
10437         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10438         # file: $path
10439         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10440         #
10441         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10442
10443         getfattr --absolute-names --encoding=base64 --name=$name $path |
10444                 awk -F= -v name=$name '$1 == name {
10445                         print substr($0, index($0, "=") + 1);
10446         }'
10447 }
10448
10449 test_102n() { # LU-4101 mdt: protect internal xattrs
10450         [ -z "$(which setfattr 2>/dev/null)" ] &&
10451                 skip "could not find setfattr"
10452         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10453         then
10454                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10455         fi
10456
10457         local file0=$DIR/$tfile.0
10458         local file1=$DIR/$tfile.1
10459         local xattr0=$TMP/$tfile.0
10460         local xattr1=$TMP/$tfile.1
10461         local namelist="lov lma lmv link fid version som hsm"
10462         local name
10463         local value
10464
10465         rm -rf $file0 $file1 $xattr0 $xattr1
10466         touch $file0 $file1
10467
10468         # Get 'before' xattrs of $file1.
10469         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10470
10471         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10472                 namelist+=" lfsck_namespace"
10473         for name in $namelist; do
10474                 # Try to copy xattr from $file0 to $file1.
10475                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10476
10477                 setfattr --name=trusted.$name --value="$value" $file1 ||
10478                         error "setxattr 'trusted.$name' failed"
10479
10480                 # Try to set a garbage xattr.
10481                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10482
10483                 if [[ x$name == "xlov" ]]; then
10484                         setfattr --name=trusted.lov --value="$value" $file1 &&
10485                         error "setxattr invalid 'trusted.lov' success"
10486                 else
10487                         setfattr --name=trusted.$name --value="$value" $file1 ||
10488                                 error "setxattr invalid 'trusted.$name' failed"
10489                 fi
10490
10491                 # Try to remove the xattr from $file1. We don't care if this
10492                 # appears to succeed or fail, we just don't want there to be
10493                 # any changes or crashes.
10494                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10495         done
10496
10497         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10498         then
10499                 name="lfsck_ns"
10500                 # Try to copy xattr from $file0 to $file1.
10501                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10502
10503                 setfattr --name=trusted.$name --value="$value" $file1 ||
10504                         error "setxattr 'trusted.$name' failed"
10505
10506                 # Try to set a garbage xattr.
10507                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10508
10509                 setfattr --name=trusted.$name --value="$value" $file1 ||
10510                         error "setxattr 'trusted.$name' failed"
10511
10512                 # Try to remove the xattr from $file1. We don't care if this
10513                 # appears to succeed or fail, we just don't want there to be
10514                 # any changes or crashes.
10515                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10516         fi
10517
10518         # Get 'after' xattrs of file1.
10519         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10520
10521         if ! diff $xattr0 $xattr1; then
10522                 error "before and after xattrs of '$file1' differ"
10523         fi
10524
10525         rm -rf $file0 $file1 $xattr0 $xattr1
10526
10527         return 0
10528 }
10529 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10530
10531 test_102p() { # LU-4703 setxattr did not check ownership
10532         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10533                 skip "MDS needs to be at least 2.5.56"
10534
10535         local testfile=$DIR/$tfile
10536
10537         touch $testfile
10538
10539         echo "setfacl as user..."
10540         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10541         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10542
10543         echo "setfattr as user..."
10544         setfacl -m "u:$RUNAS_ID:---" $testfile
10545         $RUNAS setfattr -x system.posix_acl_access $testfile
10546         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10547 }
10548 run_test 102p "check setxattr(2) correctly fails without permission"
10549
10550 test_102q() {
10551         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10552                 skip "MDS needs to be at least 2.6.92"
10553
10554         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10555 }
10556 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10557
10558 test_102r() {
10559         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10560                 skip "MDS needs to be at least 2.6.93"
10561
10562         touch $DIR/$tfile || error "touch"
10563         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10564         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10565         rm $DIR/$tfile || error "rm"
10566
10567         #normal directory
10568         mkdir -p $DIR/$tdir || error "mkdir"
10569         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10570         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10571         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10572                 error "$testfile error deleting user.author1"
10573         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10574                 grep "user.$(basename $tdir)" &&
10575                 error "$tdir did not delete user.$(basename $tdir)"
10576         rmdir $DIR/$tdir || error "rmdir"
10577
10578         #striped directory
10579         test_mkdir $DIR/$tdir
10580         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10581         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10582         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10583                 error "$testfile error deleting user.author1"
10584         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10585                 grep "user.$(basename $tdir)" &&
10586                 error "$tdir did not delete user.$(basename $tdir)"
10587         rmdir $DIR/$tdir || error "rm striped dir"
10588 }
10589 run_test 102r "set EAs with empty values"
10590
10591 test_102s() {
10592         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10593                 skip "MDS needs to be at least 2.11.52"
10594
10595         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10596
10597         save_lustre_params client "llite.*.xattr_cache" > $save
10598
10599         for cache in 0 1; do
10600                 lctl set_param llite.*.xattr_cache=$cache
10601
10602                 rm -f $DIR/$tfile
10603                 touch $DIR/$tfile || error "touch"
10604                 for prefix in lustre security system trusted user; do
10605                         # Note getxattr() may fail with 'Operation not
10606                         # supported' or 'No such attribute' depending
10607                         # on prefix and cache.
10608                         getfattr -n $prefix.n102s $DIR/$tfile &&
10609                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10610                 done
10611         done
10612
10613         restore_lustre_params < $save
10614 }
10615 run_test 102s "getting nonexistent xattrs should fail"
10616
10617 test_102t() {
10618         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10619                 skip "MDS needs to be at least 2.11.52"
10620
10621         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10622
10623         save_lustre_params client "llite.*.xattr_cache" > $save
10624
10625         for cache in 0 1; do
10626                 lctl set_param llite.*.xattr_cache=$cache
10627
10628                 for buf_size in 0 256; do
10629                         rm -f $DIR/$tfile
10630                         touch $DIR/$tfile || error "touch"
10631                         setfattr -n user.multiop $DIR/$tfile
10632                         $MULTIOP $DIR/$tfile oa$buf_size ||
10633                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10634                 done
10635         done
10636
10637         restore_lustre_params < $save
10638 }
10639 run_test 102t "zero length xattr values handled correctly"
10640
10641 run_acl_subtest()
10642 {
10643     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10644     return $?
10645 }
10646
10647 test_103a() {
10648         [ "$UID" != 0 ] && skip "must run as root"
10649         $GSS && skip_env "could not run under gss"
10650         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10651                 skip_env "must have acl enabled"
10652         [ -z "$(which setfacl 2>/dev/null)" ] &&
10653                 skip_env "could not find setfacl"
10654         remote_mds_nodsh && skip "remote MDS with nodsh"
10655
10656         gpasswd -a daemon bin                           # LU-5641
10657         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10658
10659         declare -a identity_old
10660
10661         for num in $(seq $MDSCOUNT); do
10662                 switch_identity $num true || identity_old[$num]=$?
10663         done
10664
10665         SAVE_UMASK=$(umask)
10666         umask 0022
10667         mkdir -p $DIR/$tdir
10668         cd $DIR/$tdir
10669
10670         echo "performing cp ..."
10671         run_acl_subtest cp || error "run_acl_subtest cp failed"
10672         echo "performing getfacl-noacl..."
10673         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10674         echo "performing misc..."
10675         run_acl_subtest misc || error  "misc test failed"
10676         echo "performing permissions..."
10677         run_acl_subtest permissions || error "permissions failed"
10678         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10679         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10680                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10681                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10682         then
10683                 echo "performing permissions xattr..."
10684                 run_acl_subtest permissions_xattr ||
10685                         error "permissions_xattr failed"
10686         fi
10687         echo "performing setfacl..."
10688         run_acl_subtest setfacl || error  "setfacl test failed"
10689
10690         # inheritance test got from HP
10691         echo "performing inheritance..."
10692         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10693         chmod +x make-tree || error "chmod +x failed"
10694         run_acl_subtest inheritance || error "inheritance test failed"
10695         rm -f make-tree
10696
10697         echo "LU-974 ignore umask when acl is enabled..."
10698         run_acl_subtest 974 || error "LU-974 umask test failed"
10699         if [ $MDSCOUNT -ge 2 ]; then
10700                 run_acl_subtest 974_remote ||
10701                         error "LU-974 umask test failed under remote dir"
10702         fi
10703
10704         echo "LU-2561 newly created file is same size as directory..."
10705         if [ "$mds1_FSTYPE" != "zfs" ]; then
10706                 run_acl_subtest 2561 || error "LU-2561 test failed"
10707         else
10708                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10709         fi
10710
10711         run_acl_subtest 4924 || error "LU-4924 test failed"
10712
10713         cd $SAVE_PWD
10714         umask $SAVE_UMASK
10715
10716         for num in $(seq $MDSCOUNT); do
10717                 if [ "${identity_old[$num]}" = 1 ]; then
10718                         switch_identity $num false || identity_old[$num]=$?
10719                 fi
10720         done
10721 }
10722 run_test 103a "acl test"
10723
10724 test_103b() {
10725         declare -a pids
10726         local U
10727
10728         for U in {0..511}; do
10729                 {
10730                 local O=$(printf "%04o" $U)
10731
10732                 umask $(printf "%04o" $((511 ^ $O)))
10733                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10734                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10735
10736                 (( $S == ($O & 0666) )) ||
10737                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10738
10739                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10740                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10741                 (( $S == ($O & 0666) )) ||
10742                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10743
10744                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10745                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10746                 (( $S == ($O & 0666) )) ||
10747                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10748                 rm -f $DIR/$tfile.[smp]$0
10749                 } &
10750                 local pid=$!
10751
10752                 # limit the concurrently running threads to 64. LU-11878
10753                 local idx=$((U % 64))
10754                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10755                 pids[idx]=$pid
10756         done
10757         wait
10758 }
10759 run_test 103b "umask lfs setstripe"
10760
10761 test_103c() {
10762         mkdir -p $DIR/$tdir
10763         cp -rp $DIR/$tdir $DIR/$tdir.bak
10764
10765         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10766                 error "$DIR/$tdir shouldn't contain default ACL"
10767         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10768                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10769         true
10770 }
10771 run_test 103c "'cp -rp' won't set empty acl"
10772
10773 test_103e() {
10774         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10775                 skip "MDS needs to be at least 2.13.59"
10776
10777         mkdir -p $DIR/$tdir
10778         # one default ACL will be created for the file owner
10779         for U in {2..256}; do
10780                 setfacl -m default:user:$U:rwx $DIR/$tdir
10781                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10782                 touch $DIR/$tdir/$tfile.$U ||
10783                         error "failed to create $tfile.$U with $numacl ACLs"
10784         done
10785 }
10786 run_test 103e "inheritance of big amount of default ACLs"
10787
10788 test_104a() {
10789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10790
10791         touch $DIR/$tfile
10792         lfs df || error "lfs df failed"
10793         lfs df -ih || error "lfs df -ih failed"
10794         lfs df -h $DIR || error "lfs df -h $DIR failed"
10795         lfs df -i $DIR || error "lfs df -i $DIR failed"
10796         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10797         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10798
10799         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10800         lctl --device %$OSC deactivate
10801         lfs df || error "lfs df with deactivated OSC failed"
10802         lctl --device %$OSC activate
10803         # wait the osc back to normal
10804         wait_osc_import_ready client ost
10805
10806         lfs df || error "lfs df with reactivated OSC failed"
10807         rm -f $DIR/$tfile
10808 }
10809 run_test 104a "lfs df [-ih] [path] test ========================="
10810
10811 test_104b() {
10812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10813         [ $RUNAS_ID -eq $UID ] &&
10814                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10815
10816         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10817                         grep "Permission denied" | wc -l)))
10818         if [ $denied_cnt -ne 0 ]; then
10819                 error "lfs check servers test failed"
10820         fi
10821 }
10822 run_test 104b "$RUNAS lfs check servers test ===================="
10823
10824 test_105a() {
10825         # doesn't work on 2.4 kernels
10826         touch $DIR/$tfile
10827         if $(flock_is_enabled); then
10828                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10829         else
10830                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10831         fi
10832         rm -f $DIR/$tfile
10833 }
10834 run_test 105a "flock when mounted without -o flock test ========"
10835
10836 test_105b() {
10837         touch $DIR/$tfile
10838         if $(flock_is_enabled); then
10839                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10840         else
10841                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10842         fi
10843         rm -f $DIR/$tfile
10844 }
10845 run_test 105b "fcntl when mounted without -o flock test ========"
10846
10847 test_105c() {
10848         touch $DIR/$tfile
10849         if $(flock_is_enabled); then
10850                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10851         else
10852                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10853         fi
10854         rm -f $DIR/$tfile
10855 }
10856 run_test 105c "lockf when mounted without -o flock test"
10857
10858 test_105d() { # bug 15924
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860
10861         test_mkdir $DIR/$tdir
10862         flock_is_enabled || skip_env "mount w/o flock enabled"
10863         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10864         $LCTL set_param fail_loc=0x80000315
10865         flocks_test 2 $DIR/$tdir
10866 }
10867 run_test 105d "flock race (should not freeze) ========"
10868
10869 test_105e() { # bug 22660 && 22040
10870         flock_is_enabled || skip_env "mount w/o flock enabled"
10871
10872         touch $DIR/$tfile
10873         flocks_test 3 $DIR/$tfile
10874 }
10875 run_test 105e "Two conflicting flocks from same process"
10876
10877 test_106() { #bug 10921
10878         test_mkdir $DIR/$tdir
10879         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10880         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10881 }
10882 run_test 106 "attempt exec of dir followed by chown of that dir"
10883
10884 test_107() {
10885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10886
10887         CDIR=`pwd`
10888         local file=core
10889
10890         cd $DIR
10891         rm -f $file
10892
10893         local save_pattern=$(sysctl -n kernel.core_pattern)
10894         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10895         sysctl -w kernel.core_pattern=$file
10896         sysctl -w kernel.core_uses_pid=0
10897
10898         ulimit -c unlimited
10899         sleep 60 &
10900         SLEEPPID=$!
10901
10902         sleep 1
10903
10904         kill -s 11 $SLEEPPID
10905         wait $SLEEPPID
10906         if [ -e $file ]; then
10907                 size=`stat -c%s $file`
10908                 [ $size -eq 0 ] && error "Fail to create core file $file"
10909         else
10910                 error "Fail to create core file $file"
10911         fi
10912         rm -f $file
10913         sysctl -w kernel.core_pattern=$save_pattern
10914         sysctl -w kernel.core_uses_pid=$save_uses_pid
10915         cd $CDIR
10916 }
10917 run_test 107 "Coredump on SIG"
10918
10919 test_110() {
10920         test_mkdir $DIR/$tdir
10921         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10922         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10923                 error "mkdir with 256 char should fail, but did not"
10924         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10925                 error "create with 255 char failed"
10926         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10927                 error "create with 256 char should fail, but did not"
10928
10929         ls -l $DIR/$tdir
10930         rm -rf $DIR/$tdir
10931 }
10932 run_test 110 "filename length checking"
10933
10934 #
10935 # Purpose: To verify dynamic thread (OSS) creation.
10936 #
10937 test_115() {
10938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10939         remote_ost_nodsh && skip "remote OST with nodsh"
10940
10941         # Lustre does not stop service threads once they are started.
10942         # Reset number of running threads to default.
10943         stopall
10944         setupall
10945
10946         local OSTIO_pre
10947         local save_params="$TMP/sanity-$TESTNAME.parameters"
10948
10949         # Get ll_ost_io count before I/O
10950         OSTIO_pre=$(do_facet ost1 \
10951                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10952         # Exit if lustre is not running (ll_ost_io not running).
10953         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10954
10955         echo "Starting with $OSTIO_pre threads"
10956         local thread_max=$((OSTIO_pre * 2))
10957         local rpc_in_flight=$((thread_max * 2))
10958         # Number of I/O Process proposed to be started.
10959         local nfiles
10960         local facets=$(get_facets OST)
10961
10962         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10963         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10964
10965         # Set in_flight to $rpc_in_flight
10966         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10967                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10968         nfiles=${rpc_in_flight}
10969         # Set ost thread_max to $thread_max
10970         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10971
10972         # 5 Minutes should be sufficient for max number of OSS
10973         # threads(thread_max) to be created.
10974         local timeout=300
10975
10976         # Start I/O.
10977         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10978         test_mkdir $DIR/$tdir
10979         for i in $(seq $nfiles); do
10980                 local file=$DIR/$tdir/${tfile}-$i
10981                 $LFS setstripe -c -1 -i 0 $file
10982                 ($WTL $file $timeout)&
10983         done
10984
10985         # I/O Started - Wait for thread_started to reach thread_max or report
10986         # error if thread_started is more than thread_max.
10987         echo "Waiting for thread_started to reach thread_max"
10988         local thread_started=0
10989         local end_time=$((SECONDS + timeout))
10990
10991         while [ $SECONDS -le $end_time ] ; do
10992                 echo -n "."
10993                 # Get ost i/o thread_started count.
10994                 thread_started=$(do_facet ost1 \
10995                         "$LCTL get_param \
10996                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10997                 # Break out if thread_started is equal/greater than thread_max
10998                 if [[ $thread_started -ge $thread_max ]]; then
10999                         echo ll_ost_io thread_started $thread_started, \
11000                                 equal/greater than thread_max $thread_max
11001                         break
11002                 fi
11003                 sleep 1
11004         done
11005
11006         # Cleanup - We have the numbers, Kill i/o jobs if running.
11007         jobcount=($(jobs -p))
11008         for i in $(seq 0 $((${#jobcount[@]}-1)))
11009         do
11010                 kill -9 ${jobcount[$i]}
11011                 if [ $? -ne 0 ] ; then
11012                         echo Warning: \
11013                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11014                 fi
11015         done
11016
11017         # Cleanup files left by WTL binary.
11018         for i in $(seq $nfiles); do
11019                 local file=$DIR/$tdir/${tfile}-$i
11020                 rm -rf $file
11021                 if [ $? -ne 0 ] ; then
11022                         echo "Warning: Failed to delete file $file"
11023                 fi
11024         done
11025
11026         restore_lustre_params <$save_params
11027         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11028
11029         # Error out if no new thread has started or Thread started is greater
11030         # than thread max.
11031         if [[ $thread_started -le $OSTIO_pre ||
11032                         $thread_started -gt $thread_max ]]; then
11033                 error "ll_ost_io: thread_started $thread_started" \
11034                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11035                       "No new thread started or thread started greater " \
11036                       "than thread_max."
11037         fi
11038 }
11039 run_test 115 "verify dynamic thread creation===================="
11040
11041 free_min_max () {
11042         wait_delete_completed
11043         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11044         echo "OST kbytes available: ${AVAIL[@]}"
11045         MAXV=${AVAIL[0]}
11046         MAXI=0
11047         MINV=${AVAIL[0]}
11048         MINI=0
11049         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11050                 #echo OST $i: ${AVAIL[i]}kb
11051                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11052                         MAXV=${AVAIL[i]}
11053                         MAXI=$i
11054                 fi
11055                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11056                         MINV=${AVAIL[i]}
11057                         MINI=$i
11058                 fi
11059         done
11060         echo "Min free space: OST $MINI: $MINV"
11061         echo "Max free space: OST $MAXI: $MAXV"
11062 }
11063
11064 test_116a() { # was previously test_116()
11065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11066         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11067         remote_mds_nodsh && skip "remote MDS with nodsh"
11068
11069         echo -n "Free space priority "
11070         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11071                 head -n1
11072         declare -a AVAIL
11073         free_min_max
11074
11075         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11076         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11077         trap simple_cleanup_common EXIT
11078
11079         # Check if we need to generate uneven OSTs
11080         test_mkdir -p $DIR/$tdir/OST${MINI}
11081         local FILL=$((MINV / 4))
11082         local DIFF=$((MAXV - MINV))
11083         local DIFF2=$((DIFF * 100 / MINV))
11084
11085         local threshold=$(do_facet $SINGLEMDS \
11086                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11087         threshold=${threshold%%%}
11088         echo -n "Check for uneven OSTs: "
11089         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11090
11091         if [[ $DIFF2 -gt $threshold ]]; then
11092                 echo "ok"
11093                 echo "Don't need to fill OST$MINI"
11094         else
11095                 # generate uneven OSTs. Write 2% over the QOS threshold value
11096                 echo "no"
11097                 DIFF=$((threshold - DIFF2 + 2))
11098                 DIFF2=$((MINV * DIFF / 100))
11099                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11100                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11101                         error "setstripe failed"
11102                 DIFF=$((DIFF2 / 2048))
11103                 i=0
11104                 while [ $i -lt $DIFF ]; do
11105                         i=$((i + 1))
11106                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11107                                 bs=2M count=1 2>/dev/null
11108                         echo -n .
11109                 done
11110                 echo .
11111                 sync
11112                 sleep_maxage
11113                 free_min_max
11114         fi
11115
11116         DIFF=$((MAXV - MINV))
11117         DIFF2=$((DIFF * 100 / MINV))
11118         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11119         if [ $DIFF2 -gt $threshold ]; then
11120                 echo "ok"
11121         else
11122                 echo "failed - QOS mode won't be used"
11123                 simple_cleanup_common
11124                 skip "QOS imbalance criteria not met"
11125         fi
11126
11127         MINI1=$MINI
11128         MINV1=$MINV
11129         MAXI1=$MAXI
11130         MAXV1=$MAXV
11131
11132         # now fill using QOS
11133         $LFS setstripe -c 1 $DIR/$tdir
11134         FILL=$((FILL / 200))
11135         if [ $FILL -gt 600 ]; then
11136                 FILL=600
11137         fi
11138         echo "writing $FILL files to QOS-assigned OSTs"
11139         i=0
11140         while [ $i -lt $FILL ]; do
11141                 i=$((i + 1))
11142                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11143                         count=1 2>/dev/null
11144                 echo -n .
11145         done
11146         echo "wrote $i 200k files"
11147         sync
11148         sleep_maxage
11149
11150         echo "Note: free space may not be updated, so measurements might be off"
11151         free_min_max
11152         DIFF2=$((MAXV - MINV))
11153         echo "free space delta: orig $DIFF final $DIFF2"
11154         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11155         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11156         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11157         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11158         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11159         if [[ $DIFF -gt 0 ]]; then
11160                 FILL=$((DIFF2 * 100 / DIFF - 100))
11161                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11162         fi
11163
11164         # Figure out which files were written where
11165         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11166                awk '/'$MINI1': / {print $2; exit}')
11167         echo $UUID
11168         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11169         echo "$MINC files created on smaller OST $MINI1"
11170         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11171                awk '/'$MAXI1': / {print $2; exit}')
11172         echo $UUID
11173         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11174         echo "$MAXC files created on larger OST $MAXI1"
11175         if [[ $MINC -gt 0 ]]; then
11176                 FILL=$((MAXC * 100 / MINC - 100))
11177                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11178         fi
11179         [[ $MAXC -gt $MINC ]] ||
11180                 error_ignore LU-9 "stripe QOS didn't balance free space"
11181         simple_cleanup_common
11182 }
11183 run_test 116a "stripe QOS: free space balance ==================="
11184
11185 test_116b() { # LU-2093
11186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11187         remote_mds_nodsh && skip "remote MDS with nodsh"
11188
11189 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11190         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11191                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11192         [ -z "$old_rr" ] && skip "no QOS"
11193         do_facet $SINGLEMDS lctl set_param \
11194                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11195         mkdir -p $DIR/$tdir
11196         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11197         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11198         do_facet $SINGLEMDS lctl set_param fail_loc=0
11199         rm -rf $DIR/$tdir
11200         do_facet $SINGLEMDS lctl set_param \
11201                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11202 }
11203 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11204
11205 test_117() # bug 10891
11206 {
11207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11208
11209         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11210         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11211         lctl set_param fail_loc=0x21e
11212         > $DIR/$tfile || error "truncate failed"
11213         lctl set_param fail_loc=0
11214         echo "Truncate succeeded."
11215         rm -f $DIR/$tfile
11216 }
11217 run_test 117 "verify osd extend =========="
11218
11219 NO_SLOW_RESENDCOUNT=4
11220 export OLD_RESENDCOUNT=""
11221 set_resend_count () {
11222         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11223         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11224         lctl set_param -n $PROC_RESENDCOUNT $1
11225         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11226 }
11227
11228 # for reduce test_118* time (b=14842)
11229 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11230
11231 # Reset async IO behavior after error case
11232 reset_async() {
11233         FILE=$DIR/reset_async
11234
11235         # Ensure all OSCs are cleared
11236         $LFS setstripe -c -1 $FILE
11237         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11238         sync
11239         rm $FILE
11240 }
11241
11242 test_118a() #bug 11710
11243 {
11244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11245
11246         reset_async
11247
11248         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11249         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11251
11252         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11253                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11254                 return 1;
11255         fi
11256         rm -f $DIR/$tfile
11257 }
11258 run_test 118a "verify O_SYNC works =========="
11259
11260 test_118b()
11261 {
11262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11263         remote_ost_nodsh && skip "remote OST with nodsh"
11264
11265         reset_async
11266
11267         #define OBD_FAIL_SRV_ENOENT 0x217
11268         set_nodes_failloc "$(osts_nodes)" 0x217
11269         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11270         RC=$?
11271         set_nodes_failloc "$(osts_nodes)" 0
11272         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11273         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11274                     grep -c writeback)
11275
11276         if [[ $RC -eq 0 ]]; then
11277                 error "Must return error due to dropped pages, rc=$RC"
11278                 return 1;
11279         fi
11280
11281         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11282                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11283                 return 1;
11284         fi
11285
11286         echo "Dirty pages not leaked on ENOENT"
11287
11288         # Due to the above error the OSC will issue all RPCs syncronously
11289         # until a subsequent RPC completes successfully without error.
11290         $MULTIOP $DIR/$tfile Ow4096yc
11291         rm -f $DIR/$tfile
11292
11293         return 0
11294 }
11295 run_test 118b "Reclaim dirty pages on fatal error =========="
11296
11297 test_118c()
11298 {
11299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11300
11301         # for 118c, restore the original resend count, LU-1940
11302         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11303                                 set_resend_count $OLD_RESENDCOUNT
11304         remote_ost_nodsh && skip "remote OST with nodsh"
11305
11306         reset_async
11307
11308         #define OBD_FAIL_OST_EROFS               0x216
11309         set_nodes_failloc "$(osts_nodes)" 0x216
11310
11311         # multiop should block due to fsync until pages are written
11312         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11313         MULTIPID=$!
11314         sleep 1
11315
11316         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11317                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11318         fi
11319
11320         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11321                     grep -c writeback)
11322         if [[ $WRITEBACK -eq 0 ]]; then
11323                 error "No page in writeback, writeback=$WRITEBACK"
11324         fi
11325
11326         set_nodes_failloc "$(osts_nodes)" 0
11327         wait $MULTIPID
11328         RC=$?
11329         if [[ $RC -ne 0 ]]; then
11330                 error "Multiop fsync failed, rc=$RC"
11331         fi
11332
11333         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11334         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11335                     grep -c writeback)
11336         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11337                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11338         fi
11339
11340         rm -f $DIR/$tfile
11341         echo "Dirty pages flushed via fsync on EROFS"
11342         return 0
11343 }
11344 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11345
11346 # continue to use small resend count to reduce test_118* time (b=14842)
11347 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11348
11349 test_118d()
11350 {
11351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11352         remote_ost_nodsh && skip "remote OST with nodsh"
11353
11354         reset_async
11355
11356         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11357         set_nodes_failloc "$(osts_nodes)" 0x214
11358         # multiop should block due to fsync until pages are written
11359         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11360         MULTIPID=$!
11361         sleep 1
11362
11363         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11364                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11365         fi
11366
11367         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11368                     grep -c writeback)
11369         if [[ $WRITEBACK -eq 0 ]]; then
11370                 error "No page in writeback, writeback=$WRITEBACK"
11371         fi
11372
11373         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11374         set_nodes_failloc "$(osts_nodes)" 0
11375
11376         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11377         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11378                     grep -c writeback)
11379         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11380                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11381         fi
11382
11383         rm -f $DIR/$tfile
11384         echo "Dirty pages gaurenteed flushed via fsync"
11385         return 0
11386 }
11387 run_test 118d "Fsync validation inject a delay of the bulk =========="
11388
11389 test_118f() {
11390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11391
11392         reset_async
11393
11394         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11395         lctl set_param fail_loc=0x8000040a
11396
11397         # Should simulate EINVAL error which is fatal
11398         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11399         RC=$?
11400         if [[ $RC -eq 0 ]]; then
11401                 error "Must return error due to dropped pages, rc=$RC"
11402         fi
11403
11404         lctl set_param fail_loc=0x0
11405
11406         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11407         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11408         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11409                     grep -c writeback)
11410         if [[ $LOCKED -ne 0 ]]; then
11411                 error "Locked pages remain in cache, locked=$LOCKED"
11412         fi
11413
11414         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11415                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11416         fi
11417
11418         rm -f $DIR/$tfile
11419         echo "No pages locked after fsync"
11420
11421         reset_async
11422         return 0
11423 }
11424 run_test 118f "Simulate unrecoverable OSC side error =========="
11425
11426 test_118g() {
11427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11428
11429         reset_async
11430
11431         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11432         lctl set_param fail_loc=0x406
11433
11434         # simulate local -ENOMEM
11435         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11436         RC=$?
11437
11438         lctl set_param fail_loc=0
11439         if [[ $RC -eq 0 ]]; then
11440                 error "Must return error due to dropped pages, rc=$RC"
11441         fi
11442
11443         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11444         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11445         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11446                         grep -c writeback)
11447         if [[ $LOCKED -ne 0 ]]; then
11448                 error "Locked pages remain in cache, locked=$LOCKED"
11449         fi
11450
11451         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11452                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11453         fi
11454
11455         rm -f $DIR/$tfile
11456         echo "No pages locked after fsync"
11457
11458         reset_async
11459         return 0
11460 }
11461 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11462
11463 test_118h() {
11464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11465         remote_ost_nodsh && skip "remote OST with nodsh"
11466
11467         reset_async
11468
11469         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11470         set_nodes_failloc "$(osts_nodes)" 0x20e
11471         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11472         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11473         RC=$?
11474
11475         set_nodes_failloc "$(osts_nodes)" 0
11476         if [[ $RC -eq 0 ]]; then
11477                 error "Must return error due to dropped pages, rc=$RC"
11478         fi
11479
11480         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11481         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11482         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11483                     grep -c writeback)
11484         if [[ $LOCKED -ne 0 ]]; then
11485                 error "Locked pages remain in cache, locked=$LOCKED"
11486         fi
11487
11488         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11489                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11490         fi
11491
11492         rm -f $DIR/$tfile
11493         echo "No pages locked after fsync"
11494
11495         return 0
11496 }
11497 run_test 118h "Verify timeout in handling recoverables errors  =========="
11498
11499 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11500
11501 test_118i() {
11502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11503         remote_ost_nodsh && skip "remote OST with nodsh"
11504
11505         reset_async
11506
11507         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11508         set_nodes_failloc "$(osts_nodes)" 0x20e
11509
11510         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11511         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11512         PID=$!
11513         sleep 5
11514         set_nodes_failloc "$(osts_nodes)" 0
11515
11516         wait $PID
11517         RC=$?
11518         if [[ $RC -ne 0 ]]; then
11519                 error "got error, but should be not, rc=$RC"
11520         fi
11521
11522         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11523         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11524         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11525         if [[ $LOCKED -ne 0 ]]; then
11526                 error "Locked pages remain in cache, locked=$LOCKED"
11527         fi
11528
11529         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11530                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11531         fi
11532
11533         rm -f $DIR/$tfile
11534         echo "No pages locked after fsync"
11535
11536         return 0
11537 }
11538 run_test 118i "Fix error before timeout in recoverable error  =========="
11539
11540 [ "$SLOW" = "no" ] && set_resend_count 4
11541
11542 test_118j() {
11543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11544         remote_ost_nodsh && skip "remote OST with nodsh"
11545
11546         reset_async
11547
11548         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11549         set_nodes_failloc "$(osts_nodes)" 0x220
11550
11551         # return -EIO from OST
11552         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11553         RC=$?
11554         set_nodes_failloc "$(osts_nodes)" 0x0
11555         if [[ $RC -eq 0 ]]; then
11556                 error "Must return error due to dropped pages, rc=$RC"
11557         fi
11558
11559         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11560         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11561         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11562         if [[ $LOCKED -ne 0 ]]; then
11563                 error "Locked pages remain in cache, locked=$LOCKED"
11564         fi
11565
11566         # in recoverable error on OST we want resend and stay until it finished
11567         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11568                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11569         fi
11570
11571         rm -f $DIR/$tfile
11572         echo "No pages locked after fsync"
11573
11574         return 0
11575 }
11576 run_test 118j "Simulate unrecoverable OST side error =========="
11577
11578 test_118k()
11579 {
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         remote_ost_nodsh && skip "remote OSTs with nodsh"
11582
11583         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11584         set_nodes_failloc "$(osts_nodes)" 0x20e
11585         test_mkdir $DIR/$tdir
11586
11587         for ((i=0;i<10;i++)); do
11588                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11589                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11590                 SLEEPPID=$!
11591                 sleep 0.500s
11592                 kill $SLEEPPID
11593                 wait $SLEEPPID
11594         done
11595
11596         set_nodes_failloc "$(osts_nodes)" 0
11597         rm -rf $DIR/$tdir
11598 }
11599 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11600
11601 test_118l() # LU-646
11602 {
11603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11604
11605         test_mkdir $DIR/$tdir
11606         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11607         rm -rf $DIR/$tdir
11608 }
11609 run_test 118l "fsync dir"
11610
11611 test_118m() # LU-3066
11612 {
11613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11614
11615         test_mkdir $DIR/$tdir
11616         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11617         rm -rf $DIR/$tdir
11618 }
11619 run_test 118m "fdatasync dir ========="
11620
11621 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11622
11623 test_118n()
11624 {
11625         local begin
11626         local end
11627
11628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11629         remote_ost_nodsh && skip "remote OSTs with nodsh"
11630
11631         # Sleep to avoid a cached response.
11632         #define OBD_STATFS_CACHE_SECONDS 1
11633         sleep 2
11634
11635         # Inject a 10 second delay in the OST_STATFS handler.
11636         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11637         set_nodes_failloc "$(osts_nodes)" 0x242
11638
11639         begin=$SECONDS
11640         stat --file-system $MOUNT > /dev/null
11641         end=$SECONDS
11642
11643         set_nodes_failloc "$(osts_nodes)" 0
11644
11645         if ((end - begin > 20)); then
11646             error "statfs took $((end - begin)) seconds, expected 10"
11647         fi
11648 }
11649 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11650
11651 test_119a() # bug 11737
11652 {
11653         BSIZE=$((512 * 1024))
11654         directio write $DIR/$tfile 0 1 $BSIZE
11655         # We ask to read two blocks, which is more than a file size.
11656         # directio will indicate an error when requested and actual
11657         # sizes aren't equeal (a normal situation in this case) and
11658         # print actual read amount.
11659         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11660         if [ "$NOB" != "$BSIZE" ]; then
11661                 error "read $NOB bytes instead of $BSIZE"
11662         fi
11663         rm -f $DIR/$tfile
11664 }
11665 run_test 119a "Short directIO read must return actual read amount"
11666
11667 test_119b() # bug 11737
11668 {
11669         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11670
11671         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11673         sync
11674         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11675                 error "direct read failed"
11676         rm -f $DIR/$tfile
11677 }
11678 run_test 119b "Sparse directIO read must return actual read amount"
11679
11680 test_119c() # bug 13099
11681 {
11682         BSIZE=1048576
11683         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11684         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11685         rm -f $DIR/$tfile
11686 }
11687 run_test 119c "Testing for direct read hitting hole"
11688
11689 test_119d() # bug 15950
11690 {
11691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11692
11693         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11694         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11695         BSIZE=1048576
11696         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11697         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11698         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11699         lctl set_param fail_loc=0x40d
11700         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11701         pid_dio=$!
11702         sleep 1
11703         cat $DIR/$tfile > /dev/null &
11704         lctl set_param fail_loc=0
11705         pid_reads=$!
11706         wait $pid_dio
11707         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11708         sleep 2
11709         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11710         error "the read rpcs have not completed in 2s"
11711         rm -f $DIR/$tfile
11712         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11713 }
11714 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11715
11716 test_120a() {
11717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11718         remote_mds_nodsh && skip "remote MDS with nodsh"
11719         test_mkdir -i0 -c1 $DIR/$tdir
11720         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11721                 skip_env "no early lock cancel on server"
11722
11723         lru_resize_disable mdc
11724         lru_resize_disable osc
11725         cancel_lru_locks mdc
11726         # asynchronous object destroy at MDT could cause bl ast to client
11727         cancel_lru_locks osc
11728
11729         stat $DIR/$tdir > /dev/null
11730         can1=$(do_facet mds1 \
11731                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11732                awk '/ldlm_cancel/ {print $2}')
11733         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11734                awk '/ldlm_bl_callback/ {print $2}')
11735         test_mkdir -i0 -c1 $DIR/$tdir/d1
11736         can2=$(do_facet mds1 \
11737                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11738                awk '/ldlm_cancel/ {print $2}')
11739         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11740                awk '/ldlm_bl_callback/ {print $2}')
11741         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11742         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11743         lru_resize_enable mdc
11744         lru_resize_enable osc
11745 }
11746 run_test 120a "Early Lock Cancel: mkdir test"
11747
11748 test_120b() {
11749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11750         remote_mds_nodsh && skip "remote MDS with nodsh"
11751         test_mkdir $DIR/$tdir
11752         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11753                 skip_env "no early lock cancel on server"
11754
11755         lru_resize_disable mdc
11756         lru_resize_disable osc
11757         cancel_lru_locks mdc
11758         stat $DIR/$tdir > /dev/null
11759         can1=$(do_facet $SINGLEMDS \
11760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11761                awk '/ldlm_cancel/ {print $2}')
11762         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11763                awk '/ldlm_bl_callback/ {print $2}')
11764         touch $DIR/$tdir/f1
11765         can2=$(do_facet $SINGLEMDS \
11766                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11767                awk '/ldlm_cancel/ {print $2}')
11768         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11769                awk '/ldlm_bl_callback/ {print $2}')
11770         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11771         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11772         lru_resize_enable mdc
11773         lru_resize_enable osc
11774 }
11775 run_test 120b "Early Lock Cancel: create test"
11776
11777 test_120c() {
11778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11779         remote_mds_nodsh && skip "remote MDS with nodsh"
11780         test_mkdir -i0 -c1 $DIR/$tdir
11781         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11782                 skip "no early lock cancel on server"
11783
11784         lru_resize_disable mdc
11785         lru_resize_disable osc
11786         test_mkdir -i0 -c1 $DIR/$tdir/d1
11787         test_mkdir -i0 -c1 $DIR/$tdir/d2
11788         touch $DIR/$tdir/d1/f1
11789         cancel_lru_locks mdc
11790         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11791         can1=$(do_facet mds1 \
11792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11793                awk '/ldlm_cancel/ {print $2}')
11794         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11795                awk '/ldlm_bl_callback/ {print $2}')
11796         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11797         can2=$(do_facet mds1 \
11798                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11799                awk '/ldlm_cancel/ {print $2}')
11800         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11801                awk '/ldlm_bl_callback/ {print $2}')
11802         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11803         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11804         lru_resize_enable mdc
11805         lru_resize_enable osc
11806 }
11807 run_test 120c "Early Lock Cancel: link test"
11808
11809 test_120d() {
11810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11811         remote_mds_nodsh && skip "remote MDS with nodsh"
11812         test_mkdir -i0 -c1 $DIR/$tdir
11813         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11814                 skip_env "no early lock cancel on server"
11815
11816         lru_resize_disable mdc
11817         lru_resize_disable osc
11818         touch $DIR/$tdir
11819         cancel_lru_locks mdc
11820         stat $DIR/$tdir > /dev/null
11821         can1=$(do_facet mds1 \
11822                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11823                awk '/ldlm_cancel/ {print $2}')
11824         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11825                awk '/ldlm_bl_callback/ {print $2}')
11826         chmod a+x $DIR/$tdir
11827         can2=$(do_facet mds1 \
11828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11829                awk '/ldlm_cancel/ {print $2}')
11830         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11831                awk '/ldlm_bl_callback/ {print $2}')
11832         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11833         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11834         lru_resize_enable mdc
11835         lru_resize_enable osc
11836 }
11837 run_test 120d "Early Lock Cancel: setattr test"
11838
11839 test_120e() {
11840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11841         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11842                 skip_env "no early lock cancel on server"
11843         remote_mds_nodsh && skip "remote MDS with nodsh"
11844
11845         local dlmtrace_set=false
11846
11847         test_mkdir -i0 -c1 $DIR/$tdir
11848         lru_resize_disable mdc
11849         lru_resize_disable osc
11850         ! $LCTL get_param debug | grep -q dlmtrace &&
11851                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11852         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11853         cancel_lru_locks mdc
11854         cancel_lru_locks osc
11855         dd if=$DIR/$tdir/f1 of=/dev/null
11856         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11857         # XXX client can not do early lock cancel of OST lock
11858         # during unlink (LU-4206), so cancel osc lock now.
11859         sleep 2
11860         cancel_lru_locks osc
11861         can1=$(do_facet mds1 \
11862                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11863                awk '/ldlm_cancel/ {print $2}')
11864         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11865                awk '/ldlm_bl_callback/ {print $2}')
11866         unlink $DIR/$tdir/f1
11867         sleep 5
11868         can2=$(do_facet mds1 \
11869                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11870                awk '/ldlm_cancel/ {print $2}')
11871         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11872                awk '/ldlm_bl_callback/ {print $2}')
11873         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11874                 $LCTL dk $TMP/cancel.debug.txt
11875         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11876                 $LCTL dk $TMP/blocking.debug.txt
11877         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11878         lru_resize_enable mdc
11879         lru_resize_enable osc
11880 }
11881 run_test 120e "Early Lock Cancel: unlink test"
11882
11883 test_120f() {
11884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11885         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11886                 skip_env "no early lock cancel on server"
11887         remote_mds_nodsh && skip "remote MDS with nodsh"
11888
11889         test_mkdir -i0 -c1 $DIR/$tdir
11890         lru_resize_disable mdc
11891         lru_resize_disable osc
11892         test_mkdir -i0 -c1 $DIR/$tdir/d1
11893         test_mkdir -i0 -c1 $DIR/$tdir/d2
11894         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11895         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11896         cancel_lru_locks mdc
11897         cancel_lru_locks osc
11898         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11899         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11900         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11901         # XXX client can not do early lock cancel of OST lock
11902         # during rename (LU-4206), so cancel osc lock now.
11903         sleep 2
11904         cancel_lru_locks osc
11905         can1=$(do_facet mds1 \
11906                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11907                awk '/ldlm_cancel/ {print $2}')
11908         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11909                awk '/ldlm_bl_callback/ {print $2}')
11910         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11911         sleep 5
11912         can2=$(do_facet mds1 \
11913                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11914                awk '/ldlm_cancel/ {print $2}')
11915         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11916                awk '/ldlm_bl_callback/ {print $2}')
11917         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11918         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11919         lru_resize_enable mdc
11920         lru_resize_enable osc
11921 }
11922 run_test 120f "Early Lock Cancel: rename test"
11923
11924 test_120g() {
11925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11926         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11927                 skip_env "no early lock cancel on server"
11928         remote_mds_nodsh && skip "remote MDS with nodsh"
11929
11930         lru_resize_disable mdc
11931         lru_resize_disable osc
11932         count=10000
11933         echo create $count files
11934         test_mkdir $DIR/$tdir
11935         cancel_lru_locks mdc
11936         cancel_lru_locks osc
11937         t0=$(date +%s)
11938
11939         can0=$(do_facet $SINGLEMDS \
11940                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11941                awk '/ldlm_cancel/ {print $2}')
11942         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11943                awk '/ldlm_bl_callback/ {print $2}')
11944         createmany -o $DIR/$tdir/f $count
11945         sync
11946         can1=$(do_facet $SINGLEMDS \
11947                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11948                awk '/ldlm_cancel/ {print $2}')
11949         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11950                awk '/ldlm_bl_callback/ {print $2}')
11951         t1=$(date +%s)
11952         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11953         echo rm $count files
11954         rm -r $DIR/$tdir
11955         sync
11956         can2=$(do_facet $SINGLEMDS \
11957                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11958                awk '/ldlm_cancel/ {print $2}')
11959         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11960                awk '/ldlm_bl_callback/ {print $2}')
11961         t2=$(date +%s)
11962         echo total: $count removes in $((t2-t1))
11963         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11964         sleep 2
11965         # wait for commitment of removal
11966         lru_resize_enable mdc
11967         lru_resize_enable osc
11968 }
11969 run_test 120g "Early Lock Cancel: performance test"
11970
11971 test_121() { #bug #10589
11972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11973
11974         rm -rf $DIR/$tfile
11975         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11976 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11977         lctl set_param fail_loc=0x310
11978         cancel_lru_locks osc > /dev/null
11979         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11980         lctl set_param fail_loc=0
11981         [[ $reads -eq $writes ]] ||
11982                 error "read $reads blocks, must be $writes blocks"
11983 }
11984 run_test 121 "read cancel race ========="
11985
11986 test_123a_base() { # was test 123, statahead(bug 11401)
11987         local lsx="$1"
11988
11989         SLOWOK=0
11990         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11991                 log "testing UP system. Performance may be lower than expected."
11992                 SLOWOK=1
11993         fi
11994
11995         rm -rf $DIR/$tdir
11996         test_mkdir $DIR/$tdir
11997         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11998         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11999         MULT=10
12000         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12001                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12002
12003                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12004                 lctl set_param -n llite.*.statahead_max 0
12005                 lctl get_param llite.*.statahead_max
12006                 cancel_lru_locks mdc
12007                 cancel_lru_locks osc
12008                 stime=$(date +%s)
12009                 time $lsx $DIR/$tdir | wc -l
12010                 etime=$(date +%s)
12011                 delta=$((etime - stime))
12012                 log "$lsx $i files without statahead: $delta sec"
12013                 lctl set_param llite.*.statahead_max=$max
12014
12015                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12016                         grep "statahead wrong:" | awk '{print $3}')
12017                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12018                 cancel_lru_locks mdc
12019                 cancel_lru_locks osc
12020                 stime=$(date +%s)
12021                 time $lsx $DIR/$tdir | wc -l
12022                 etime=$(date +%s)
12023                 delta_sa=$((etime - stime))
12024                 log "$lsx $i files with statahead: $delta_sa sec"
12025                 lctl get_param -n llite.*.statahead_stats
12026                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12027                         grep "statahead wrong:" | awk '{print $3}')
12028
12029                 [[ $swrong -lt $ewrong ]] &&
12030                         log "statahead was stopped, maybe too many locks held!"
12031                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12032
12033                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12034                         max=$(lctl get_param -n llite.*.statahead_max |
12035                                 head -n 1)
12036                         lctl set_param -n llite.*.statahead_max 0
12037                         lctl get_param llite.*.statahead_max
12038                         cancel_lru_locks mdc
12039                         cancel_lru_locks osc
12040                         stime=$(date +%s)
12041                         time $lsx $DIR/$tdir | wc -l
12042                         etime=$(date +%s)
12043                         delta=$((etime - stime))
12044                         log "$lsx $i files again without statahead: $delta sec"
12045                         lctl set_param llite.*.statahead_max=$max
12046                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12047                                 if [  $SLOWOK -eq 0 ]; then
12048                                         error "$lsx $i files is slower with statahead!"
12049                                 else
12050                                         log "$lsx $i files is slower with statahead!"
12051                                 fi
12052                                 break
12053                         fi
12054                 fi
12055
12056                 [ $delta -gt 20 ] && break
12057                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12058                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12059         done
12060         log "$lsx done"
12061
12062         stime=$(date +%s)
12063         rm -r $DIR/$tdir
12064         sync
12065         etime=$(date +%s)
12066         delta=$((etime - stime))
12067         log "rm -r $DIR/$tdir/: $delta seconds"
12068         log "rm done"
12069         lctl get_param -n llite.*.statahead_stats
12070 }
12071
12072 test_123aa() {
12073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12074
12075         test_123a_base "ls -l"
12076 }
12077 run_test 123aa "verify statahead work"
12078
12079 test_123ab() {
12080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12081
12082         statx_supported || skip_env "Test must be statx() syscall supported"
12083
12084         test_123a_base "$STATX -l"
12085 }
12086 run_test 123ab "verify statahead work by using statx"
12087
12088 test_123ac() {
12089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12090
12091         statx_supported || skip_env "Test must be statx() syscall supported"
12092
12093         local rpcs_before
12094         local rpcs_after
12095         local agl_before
12096         local agl_after
12097
12098         cancel_lru_locks $OSC
12099         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12100         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12101                 awk '/agl.total:/ {print $3}')
12102         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12103         test_123a_base "$STATX --cached=always -D"
12104         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12105                 awk '/agl.total:/ {print $3}')
12106         [ $agl_before -eq $agl_after ] ||
12107                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12108         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12109         [ $rpcs_after -eq $rpcs_before ] ||
12110                 error "$STATX should not send glimpse RPCs to $OSC"
12111 }
12112 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12113
12114 test_123b () { # statahead(bug 15027)
12115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12116
12117         test_mkdir $DIR/$tdir
12118         createmany -o $DIR/$tdir/$tfile-%d 1000
12119
12120         cancel_lru_locks mdc
12121         cancel_lru_locks osc
12122
12123 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12124         lctl set_param fail_loc=0x80000803
12125         ls -lR $DIR/$tdir > /dev/null
12126         log "ls done"
12127         lctl set_param fail_loc=0x0
12128         lctl get_param -n llite.*.statahead_stats
12129         rm -r $DIR/$tdir
12130         sync
12131
12132 }
12133 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12134
12135 test_123c() {
12136         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12137
12138         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12139         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12140         touch $DIR/$tdir.1/{1..3}
12141         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12142
12143         remount_client $MOUNT
12144
12145         $MULTIOP $DIR/$tdir.0 Q
12146
12147         # let statahead to complete
12148         ls -l $DIR/$tdir.0 > /dev/null
12149
12150         testid=$(echo $TESTNAME | tr '_' ' ')
12151         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12152                 error "statahead warning" || true
12153 }
12154 run_test 123c "Can not initialize inode warning on DNE statahead"
12155
12156 test_124a() {
12157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12158         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12159                 skip_env "no lru resize on server"
12160
12161         local NR=2000
12162
12163         test_mkdir $DIR/$tdir
12164
12165         log "create $NR files at $DIR/$tdir"
12166         createmany -o $DIR/$tdir/f $NR ||
12167                 error "failed to create $NR files in $DIR/$tdir"
12168
12169         cancel_lru_locks mdc
12170         ls -l $DIR/$tdir > /dev/null
12171
12172         local NSDIR=""
12173         local LRU_SIZE=0
12174         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12175                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12176                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12177                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12178                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12179                         log "NSDIR=$NSDIR"
12180                         log "NS=$(basename $NSDIR)"
12181                         break
12182                 fi
12183         done
12184
12185         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12186                 skip "Not enough cached locks created!"
12187         fi
12188         log "LRU=$LRU_SIZE"
12189
12190         local SLEEP=30
12191
12192         # We know that lru resize allows one client to hold $LIMIT locks
12193         # for 10h. After that locks begin to be killed by client.
12194         local MAX_HRS=10
12195         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12196         log "LIMIT=$LIMIT"
12197         if [ $LIMIT -lt $LRU_SIZE ]; then
12198                 skip "Limit is too small $LIMIT"
12199         fi
12200
12201         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12202         # killing locks. Some time was spent for creating locks. This means
12203         # that up to the moment of sleep finish we must have killed some of
12204         # them (10-100 locks). This depends on how fast ther were created.
12205         # Many of them were touched in almost the same moment and thus will
12206         # be killed in groups.
12207         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12208
12209         # Use $LRU_SIZE_B here to take into account real number of locks
12210         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12211         local LRU_SIZE_B=$LRU_SIZE
12212         log "LVF=$LVF"
12213         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12214         log "OLD_LVF=$OLD_LVF"
12215         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12216
12217         # Let's make sure that we really have some margin. Client checks
12218         # cached locks every 10 sec.
12219         SLEEP=$((SLEEP+20))
12220         log "Sleep ${SLEEP} sec"
12221         local SEC=0
12222         while ((SEC<$SLEEP)); do
12223                 echo -n "..."
12224                 sleep 5
12225                 SEC=$((SEC+5))
12226                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12227                 echo -n "$LRU_SIZE"
12228         done
12229         echo ""
12230         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12231         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12232
12233         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12234                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12235                 unlinkmany $DIR/$tdir/f $NR
12236                 return
12237         }
12238
12239         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12240         log "unlink $NR files at $DIR/$tdir"
12241         unlinkmany $DIR/$tdir/f $NR
12242 }
12243 run_test 124a "lru resize ======================================="
12244
12245 get_max_pool_limit()
12246 {
12247         local limit=$($LCTL get_param \
12248                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12249         local max=0
12250         for l in $limit; do
12251                 if [[ $l -gt $max ]]; then
12252                         max=$l
12253                 fi
12254         done
12255         echo $max
12256 }
12257
12258 test_124b() {
12259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12260         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12261                 skip_env "no lru resize on server"
12262
12263         LIMIT=$(get_max_pool_limit)
12264
12265         NR=$(($(default_lru_size)*20))
12266         if [[ $NR -gt $LIMIT ]]; then
12267                 log "Limit lock number by $LIMIT locks"
12268                 NR=$LIMIT
12269         fi
12270
12271         IFree=$(mdsrate_inodes_available)
12272         if [ $IFree -lt $NR ]; then
12273                 log "Limit lock number by $IFree inodes"
12274                 NR=$IFree
12275         fi
12276
12277         lru_resize_disable mdc
12278         test_mkdir -p $DIR/$tdir/disable_lru_resize
12279
12280         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12281         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12282         cancel_lru_locks mdc
12283         stime=`date +%s`
12284         PID=""
12285         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12286         PID="$PID $!"
12287         sleep 2
12288         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12289         PID="$PID $!"
12290         sleep 2
12291         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12292         PID="$PID $!"
12293         wait $PID
12294         etime=`date +%s`
12295         nolruresize_delta=$((etime-stime))
12296         log "ls -la time: $nolruresize_delta seconds"
12297         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12298         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12299
12300         lru_resize_enable mdc
12301         test_mkdir -p $DIR/$tdir/enable_lru_resize
12302
12303         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12304         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12305         cancel_lru_locks mdc
12306         stime=`date +%s`
12307         PID=""
12308         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12309         PID="$PID $!"
12310         sleep 2
12311         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12312         PID="$PID $!"
12313         sleep 2
12314         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12315         PID="$PID $!"
12316         wait $PID
12317         etime=`date +%s`
12318         lruresize_delta=$((etime-stime))
12319         log "ls -la time: $lruresize_delta seconds"
12320         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12321
12322         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12323                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12324         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12325                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12326         else
12327                 log "lru resize performs the same with no lru resize"
12328         fi
12329         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12330 }
12331 run_test 124b "lru resize (performance test) ======================="
12332
12333 test_124c() {
12334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12335         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12336                 skip_env "no lru resize on server"
12337
12338         # cache ununsed locks on client
12339         local nr=100
12340         cancel_lru_locks mdc
12341         test_mkdir $DIR/$tdir
12342         createmany -o $DIR/$tdir/f $nr ||
12343                 error "failed to create $nr files in $DIR/$tdir"
12344         ls -l $DIR/$tdir > /dev/null
12345
12346         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12347         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12348         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12349         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12350         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12351
12352         # set lru_max_age to 1 sec
12353         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12354         echo "sleep $((recalc_p * 2)) seconds..."
12355         sleep $((recalc_p * 2))
12356
12357         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12358         # restore lru_max_age
12359         $LCTL set_param -n $nsdir.lru_max_age $max_age
12360         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12361         unlinkmany $DIR/$tdir/f $nr
12362 }
12363 run_test 124c "LRUR cancel very aged locks"
12364
12365 test_124d() {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12368                 skip_env "no lru resize on server"
12369
12370         # cache ununsed locks on client
12371         local nr=100
12372
12373         lru_resize_disable mdc
12374         stack_trap "lru_resize_enable mdc" EXIT
12375
12376         cancel_lru_locks mdc
12377
12378         # asynchronous object destroy at MDT could cause bl ast to client
12379         test_mkdir $DIR/$tdir
12380         createmany -o $DIR/$tdir/f $nr ||
12381                 error "failed to create $nr files in $DIR/$tdir"
12382         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12383
12384         ls -l $DIR/$tdir > /dev/null
12385
12386         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12387         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12388         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12389         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12390
12391         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12392
12393         # set lru_max_age to 1 sec
12394         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12395         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12396
12397         echo "sleep $((recalc_p * 2)) seconds..."
12398         sleep $((recalc_p * 2))
12399
12400         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12401
12402         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12403 }
12404 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12405
12406 test_125() { # 13358
12407         $LCTL get_param -n llite.*.client_type | grep -q local ||
12408                 skip "must run as local client"
12409         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12410                 skip_env "must have acl enabled"
12411         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12412
12413         test_mkdir $DIR/$tdir
12414         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12415         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12416         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12417 }
12418 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12419
12420 test_126() { # bug 12829/13455
12421         $GSS && skip_env "must run as gss disabled"
12422         $LCTL get_param -n llite.*.client_type | grep -q local ||
12423                 skip "must run as local client"
12424         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12425
12426         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12427         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12428         rm -f $DIR/$tfile
12429         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12430 }
12431 run_test 126 "check that the fsgid provided by the client is taken into account"
12432
12433 test_127a() { # bug 15521
12434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12435         local name count samp unit min max sum sumsq
12436
12437         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12438         echo "stats before reset"
12439         $LCTL get_param osc.*.stats
12440         $LCTL set_param osc.*.stats=0
12441         local fsize=$((2048 * 1024))
12442
12443         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12444         cancel_lru_locks osc
12445         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12446
12447         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12448         stack_trap "rm -f $TMP/$tfile.tmp"
12449         while read name count samp unit min max sum sumsq; do
12450                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12451                 [ ! $min ] && error "Missing min value for $name proc entry"
12452                 eval $name=$count || error "Wrong proc format"
12453
12454                 case $name in
12455                 read_bytes|write_bytes)
12456                         [[ "$unit" =~ "bytes" ]] ||
12457                                 error "unit is not 'bytes': $unit"
12458                         (( $min >= 4096 )) || error "min is too small: $min"
12459                         (( $min <= $fsize )) || error "min is too big: $min"
12460                         (( $max >= 4096 )) || error "max is too small: $max"
12461                         (( $max <= $fsize )) || error "max is too big: $max"
12462                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12463                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12464                                 error "sumsquare is too small: $sumsq"
12465                         (( $sumsq <= $fsize * $fsize )) ||
12466                                 error "sumsquare is too big: $sumsq"
12467                         ;;
12468                 ost_read|ost_write)
12469                         [[ "$unit" =~ "usec" ]] ||
12470                                 error "unit is not 'usec': $unit"
12471                         ;;
12472                 *)      ;;
12473                 esac
12474         done < $DIR/$tfile.tmp
12475
12476         #check that we actually got some stats
12477         [ "$read_bytes" ] || error "Missing read_bytes stats"
12478         [ "$write_bytes" ] || error "Missing write_bytes stats"
12479         [ "$read_bytes" != 0 ] || error "no read done"
12480         [ "$write_bytes" != 0 ] || error "no write done"
12481 }
12482 run_test 127a "verify the client stats are sane"
12483
12484 test_127b() { # bug LU-333
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486         local name count samp unit min max sum sumsq
12487
12488         echo "stats before reset"
12489         $LCTL get_param llite.*.stats
12490         $LCTL set_param llite.*.stats=0
12491
12492         # perform 2 reads and writes so MAX is different from SUM.
12493         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12494         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12495         cancel_lru_locks osc
12496         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12497         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12498
12499         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12500         stack_trap "rm -f $TMP/$tfile.tmp"
12501         while read name count samp unit min max sum sumsq; do
12502                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12503                 eval $name=$count || error "Wrong proc format"
12504
12505                 case $name in
12506                 read_bytes|write_bytes)
12507                         [[ "$unit" =~ "bytes" ]] ||
12508                                 error "unit is not 'bytes': $unit"
12509                         (( $count == 2 )) || error "count is not 2: $count"
12510                         (( $min == $PAGE_SIZE )) ||
12511                                 error "min is not $PAGE_SIZE: $min"
12512                         (( $max == $PAGE_SIZE )) ||
12513                                 error "max is not $PAGE_SIZE: $max"
12514                         (( $sum == $PAGE_SIZE * 2 )) ||
12515                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12516                         ;;
12517                 read|write)
12518                         [[ "$unit" =~ "usec" ]] ||
12519                                 error "unit is not 'usec': $unit"
12520                         ;;
12521                 *)      ;;
12522                 esac
12523         done < $TMP/$tfile.tmp
12524
12525         #check that we actually got some stats
12526         [ "$read_bytes" ] || error "Missing read_bytes stats"
12527         [ "$write_bytes" ] || error "Missing write_bytes stats"
12528         [ "$read_bytes" != 0 ] || error "no read done"
12529         [ "$write_bytes" != 0 ] || error "no write done"
12530 }
12531 run_test 127b "verify the llite client stats are sane"
12532
12533 test_127c() { # LU-12394
12534         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12535         local size
12536         local bsize
12537         local reads
12538         local writes
12539         local count
12540
12541         $LCTL set_param llite.*.extents_stats=1
12542         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12543
12544         # Use two stripes so there is enough space in default config
12545         $LFS setstripe -c 2 $DIR/$tfile
12546
12547         # Extent stats start at 0-4K and go in power of two buckets
12548         # LL_HIST_START = 12 --> 2^12 = 4K
12549         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12550         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12551         # small configs
12552         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12553                 do
12554                 # Write and read, 2x each, second time at a non-zero offset
12555                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12556                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12557                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12558                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12559                 rm -f $DIR/$tfile
12560         done
12561
12562         $LCTL get_param llite.*.extents_stats
12563
12564         count=2
12565         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12566                 do
12567                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12568                                 grep -m 1 $bsize)
12569                 reads=$(echo $bucket | awk '{print $5}')
12570                 writes=$(echo $bucket | awk '{print $9}')
12571                 [ "$reads" -eq $count ] ||
12572                         error "$reads reads in < $bsize bucket, expect $count"
12573                 [ "$writes" -eq $count ] ||
12574                         error "$writes writes in < $bsize bucket, expect $count"
12575         done
12576
12577         # Test mmap write and read
12578         $LCTL set_param llite.*.extents_stats=c
12579         size=512
12580         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12581         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12582         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12583
12584         $LCTL get_param llite.*.extents_stats
12585
12586         count=$(((size*1024) / PAGE_SIZE))
12587
12588         bsize=$((2 * PAGE_SIZE / 1024))K
12589
12590         bucket=$($LCTL get_param -n llite.*.extents_stats |
12591                         grep -m 1 $bsize)
12592         reads=$(echo $bucket | awk '{print $5}')
12593         writes=$(echo $bucket | awk '{print $9}')
12594         # mmap writes fault in the page first, creating an additonal read
12595         [ "$reads" -eq $((2 * count)) ] ||
12596                 error "$reads reads in < $bsize bucket, expect $count"
12597         [ "$writes" -eq $count ] ||
12598                 error "$writes writes in < $bsize bucket, expect $count"
12599 }
12600 run_test 127c "test llite extent stats with regular & mmap i/o"
12601
12602 test_128() { # bug 15212
12603         touch $DIR/$tfile
12604         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12605                 find $DIR/$tfile
12606                 find $DIR/$tfile
12607         EOF
12608
12609         result=$(grep error $TMP/$tfile.log)
12610         rm -f $DIR/$tfile $TMP/$tfile.log
12611         [ -z "$result" ] ||
12612                 error "consecutive find's under interactive lfs failed"
12613 }
12614 run_test 128 "interactive lfs for 2 consecutive find's"
12615
12616 set_dir_limits () {
12617         local mntdev
12618         local canondev
12619         local node
12620
12621         local ldproc=/proc/fs/ldiskfs
12622         local facets=$(get_facets MDS)
12623
12624         for facet in ${facets//,/ }; do
12625                 canondev=$(ldiskfs_canon \
12626                            *.$(convert_facet2label $facet).mntdev $facet)
12627                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12628                         ldproc=/sys/fs/ldiskfs
12629                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12630                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12631         done
12632 }
12633
12634 check_mds_dmesg() {
12635         local facets=$(get_facets MDS)
12636         for facet in ${facets//,/ }; do
12637                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12638         done
12639         return 1
12640 }
12641
12642 test_129() {
12643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12644         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12645                 skip "Need MDS version with at least 2.5.56"
12646         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12647                 skip_env "ldiskfs only test"
12648         fi
12649         remote_mds_nodsh && skip "remote MDS with nodsh"
12650
12651         local ENOSPC=28
12652         local has_warning=false
12653
12654         rm -rf $DIR/$tdir
12655         mkdir -p $DIR/$tdir
12656
12657         # block size of mds1
12658         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12659         set_dir_limits $maxsize $((maxsize * 6 / 8))
12660         stack_trap "set_dir_limits 0 0"
12661         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12662         local dirsize=$(stat -c%s "$DIR/$tdir")
12663         local nfiles=0
12664         while (( $dirsize <= $maxsize )); do
12665                 $MCREATE $DIR/$tdir/file_base_$nfiles
12666                 rc=$?
12667                 # check two errors:
12668                 # ENOSPC for ext4 max_dir_size, which has been used since
12669                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12670                 if (( rc == ENOSPC )); then
12671                         set_dir_limits 0 0
12672                         echo "rc=$rc returned as expected after $nfiles files"
12673
12674                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12675                                 error "create failed w/o dir size limit"
12676
12677                         # messages may be rate limited if test is run repeatedly
12678                         check_mds_dmesg '"is approaching max"' ||
12679                                 echo "warning message should be output"
12680                         check_mds_dmesg '"has reached max"' ||
12681                                 echo "reached message should be output"
12682
12683                         dirsize=$(stat -c%s "$DIR/$tdir")
12684
12685                         [[ $dirsize -ge $maxsize ]] && return 0
12686                         error "dirsize $dirsize < $maxsize after $nfiles files"
12687                 elif (( rc != 0 )); then
12688                         break
12689                 fi
12690                 nfiles=$((nfiles + 1))
12691                 dirsize=$(stat -c%s "$DIR/$tdir")
12692         done
12693
12694         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12695 }
12696 run_test 129 "test directory size limit ========================"
12697
12698 OLDIFS="$IFS"
12699 cleanup_130() {
12700         trap 0
12701         IFS="$OLDIFS"
12702 }
12703
12704 test_130a() {
12705         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12706         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12707
12708         trap cleanup_130 EXIT RETURN
12709
12710         local fm_file=$DIR/$tfile
12711         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12712         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12713                 error "dd failed for $fm_file"
12714
12715         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12716         filefrag -ves $fm_file
12717         RC=$?
12718         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12719                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12720         [ $RC != 0 ] && error "filefrag $fm_file failed"
12721
12722         filefrag_op=$(filefrag -ve -k $fm_file |
12723                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12724         lun=$($LFS getstripe -i $fm_file)
12725
12726         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12727         IFS=$'\n'
12728         tot_len=0
12729         for line in $filefrag_op
12730         do
12731                 frag_lun=`echo $line | cut -d: -f5`
12732                 ext_len=`echo $line | cut -d: -f4`
12733                 if (( $frag_lun != $lun )); then
12734                         cleanup_130
12735                         error "FIEMAP on 1-stripe file($fm_file) failed"
12736                         return
12737                 fi
12738                 (( tot_len += ext_len ))
12739         done
12740
12741         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12742                 cleanup_130
12743                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12744                 return
12745         fi
12746
12747         cleanup_130
12748
12749         echo "FIEMAP on single striped file succeeded"
12750 }
12751 run_test 130a "FIEMAP (1-stripe file)"
12752
12753 test_130b() {
12754         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12755
12756         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12757         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12758
12759         trap cleanup_130 EXIT RETURN
12760
12761         local fm_file=$DIR/$tfile
12762         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12763                         error "setstripe on $fm_file"
12764         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12765                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12766
12767         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12768                 error "dd failed on $fm_file"
12769
12770         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12771         filefrag_op=$(filefrag -ve -k $fm_file |
12772                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12773
12774         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12775                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12776
12777         IFS=$'\n'
12778         tot_len=0
12779         num_luns=1
12780         for line in $filefrag_op
12781         do
12782                 frag_lun=$(echo $line | cut -d: -f5 |
12783                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12784                 ext_len=$(echo $line | cut -d: -f4)
12785                 if (( $frag_lun != $last_lun )); then
12786                         if (( tot_len != 1024 )); then
12787                                 cleanup_130
12788                                 error "FIEMAP on $fm_file failed; returned " \
12789                                 "len $tot_len for OST $last_lun instead of 1024"
12790                                 return
12791                         else
12792                                 (( num_luns += 1 ))
12793                                 tot_len=0
12794                         fi
12795                 fi
12796                 (( tot_len += ext_len ))
12797                 last_lun=$frag_lun
12798         done
12799         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12800                 cleanup_130
12801                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12802                         "luns or wrong len for OST $last_lun"
12803                 return
12804         fi
12805
12806         cleanup_130
12807
12808         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12809 }
12810 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12811
12812 test_130c() {
12813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12814
12815         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12816         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12817
12818         trap cleanup_130 EXIT RETURN
12819
12820         local fm_file=$DIR/$tfile
12821         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12822         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12823                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12824
12825         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12826                         error "dd failed on $fm_file"
12827
12828         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12829         filefrag_op=$(filefrag -ve -k $fm_file |
12830                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12831
12832         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12833                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12834
12835         IFS=$'\n'
12836         tot_len=0
12837         num_luns=1
12838         for line in $filefrag_op
12839         do
12840                 frag_lun=$(echo $line | cut -d: -f5 |
12841                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12842                 ext_len=$(echo $line | cut -d: -f4)
12843                 if (( $frag_lun != $last_lun )); then
12844                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12845                         if (( logical != 512 )); then
12846                                 cleanup_130
12847                                 error "FIEMAP on $fm_file failed; returned " \
12848                                 "logical start for lun $logical instead of 512"
12849                                 return
12850                         fi
12851                         if (( tot_len != 512 )); then
12852                                 cleanup_130
12853                                 error "FIEMAP on $fm_file failed; returned " \
12854                                 "len $tot_len for OST $last_lun instead of 1024"
12855                                 return
12856                         else
12857                                 (( num_luns += 1 ))
12858                                 tot_len=0
12859                         fi
12860                 fi
12861                 (( tot_len += ext_len ))
12862                 last_lun=$frag_lun
12863         done
12864         if (( num_luns != 2 || tot_len != 512 )); then
12865                 cleanup_130
12866                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12867                         "luns or wrong len for OST $last_lun"
12868                 return
12869         fi
12870
12871         cleanup_130
12872
12873         echo "FIEMAP on 2-stripe file with hole succeeded"
12874 }
12875 run_test 130c "FIEMAP (2-stripe file with hole)"
12876
12877 test_130d() {
12878         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12879
12880         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12881         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12882
12883         trap cleanup_130 EXIT RETURN
12884
12885         local fm_file=$DIR/$tfile
12886         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12887                         error "setstripe on $fm_file"
12888         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12889                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12890
12891         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12892         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12893                 error "dd failed on $fm_file"
12894
12895         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12896         filefrag_op=$(filefrag -ve -k $fm_file |
12897                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12898
12899         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12900                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12901
12902         IFS=$'\n'
12903         tot_len=0
12904         num_luns=1
12905         for line in $filefrag_op
12906         do
12907                 frag_lun=$(echo $line | cut -d: -f5 |
12908                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12909                 ext_len=$(echo $line | cut -d: -f4)
12910                 if (( $frag_lun != $last_lun )); then
12911                         if (( tot_len != 1024 )); then
12912                                 cleanup_130
12913                                 error "FIEMAP on $fm_file failed; returned " \
12914                                 "len $tot_len for OST $last_lun instead of 1024"
12915                                 return
12916                         else
12917                                 (( num_luns += 1 ))
12918                                 tot_len=0
12919                         fi
12920                 fi
12921                 (( tot_len += ext_len ))
12922                 last_lun=$frag_lun
12923         done
12924         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12925                 cleanup_130
12926                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12927                         "luns or wrong len for OST $last_lun"
12928                 return
12929         fi
12930
12931         cleanup_130
12932
12933         echo "FIEMAP on N-stripe file succeeded"
12934 }
12935 run_test 130d "FIEMAP (N-stripe file)"
12936
12937 test_130e() {
12938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12939
12940         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12941         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12942
12943         trap cleanup_130 EXIT RETURN
12944
12945         local fm_file=$DIR/$tfile
12946         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12947
12948         NUM_BLKS=512
12949         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12950         for ((i = 0; i < $NUM_BLKS; i++)); do
12951                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12952                         conv=notrunc > /dev/null 2>&1
12953         done
12954
12955         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12956         filefrag_op=$(filefrag -ve -k $fm_file |
12957                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12958
12959         last_lun=$(echo $filefrag_op | cut -d: -f5)
12960
12961         IFS=$'\n'
12962         tot_len=0
12963         num_luns=1
12964         for line in $filefrag_op; do
12965                 frag_lun=$(echo $line | cut -d: -f5)
12966                 ext_len=$(echo $line | cut -d: -f4)
12967                 if [[ "$frag_lun" != "$last_lun" ]]; then
12968                         if (( tot_len != $EXPECTED_LEN )); then
12969                                 cleanup_130
12970                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12971                         else
12972                                 (( num_luns += 1 ))
12973                                 tot_len=0
12974                         fi
12975                 fi
12976                 (( tot_len += ext_len ))
12977                 last_lun=$frag_lun
12978         done
12979         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12980                 cleanup_130
12981                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12982         fi
12983
12984         echo "FIEMAP with continuation calls succeeded"
12985 }
12986 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12987
12988 test_130f() {
12989         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12990         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12991
12992         local fm_file=$DIR/$tfile
12993         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12994                 error "multiop create with lov_delay_create on $fm_file"
12995
12996         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12997         filefrag_extents=$(filefrag -vek $fm_file |
12998                            awk '/extents? found/ { print $2 }')
12999         if [[ "$filefrag_extents" != "0" ]]; then
13000                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13001         fi
13002
13003         rm -f $fm_file
13004 }
13005 run_test 130f "FIEMAP (unstriped file)"
13006
13007 test_130g() {
13008         local file=$DIR/$tfile
13009         local nr=$((OSTCOUNT * 100))
13010
13011         $LFS setstripe -C $nr $file ||
13012                 error "failed to setstripe -C $nr $file"
13013
13014         dd if=/dev/zero of=$file count=$nr bs=1M
13015         sync
13016         nr=$($LFS getstripe -c $file)
13017
13018         local extents=$(filefrag -v $file |
13019                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13020
13021         echo "filefrag list $extents extents in file with stripecount $nr"
13022         if (( extents < nr )); then
13023                 $LFS getstripe $file
13024                 filefrag -v $file
13025                 error "filefrag printed $extents < $nr extents"
13026         fi
13027
13028         rm -f $file
13029 }
13030 run_test 130g "FIEMAP (overstripe file)"
13031
13032 # Test for writev/readv
13033 test_131a() {
13034         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13035                 error "writev test failed"
13036         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13037                 error "readv failed"
13038         rm -f $DIR/$tfile
13039 }
13040 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13041
13042 test_131b() {
13043         local fsize=$((524288 + 1048576 + 1572864))
13044         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13045                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13046                         error "append writev test failed"
13047
13048         ((fsize += 1572864 + 1048576))
13049         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13050                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13051                         error "append writev test failed"
13052         rm -f $DIR/$tfile
13053 }
13054 run_test 131b "test append writev"
13055
13056 test_131c() {
13057         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13058         error "NOT PASS"
13059 }
13060 run_test 131c "test read/write on file w/o objects"
13061
13062 test_131d() {
13063         rwv -f $DIR/$tfile -w -n 1 1572864
13064         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13065         if [ "$NOB" != 1572864 ]; then
13066                 error "Short read filed: read $NOB bytes instead of 1572864"
13067         fi
13068         rm -f $DIR/$tfile
13069 }
13070 run_test 131d "test short read"
13071
13072 test_131e() {
13073         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13074         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13075         error "read hitting hole failed"
13076         rm -f $DIR/$tfile
13077 }
13078 run_test 131e "test read hitting hole"
13079
13080 check_stats() {
13081         local facet=$1
13082         local op=$2
13083         local want=${3:-0}
13084         local res
13085
13086         case $facet in
13087         mds*) res=$(do_facet $facet \
13088                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13089                  ;;
13090         ost*) res=$(do_facet $facet \
13091                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13092                  ;;
13093         *) error "Wrong facet '$facet'" ;;
13094         esac
13095         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13096         # if the argument $3 is zero, it means any stat increment is ok.
13097         if [[ $want -gt 0 ]]; then
13098                 local count=$(echo $res | awk '{ print $2 }')
13099                 [[ $count -ne $want ]] &&
13100                         error "The $op counter on $facet is $count, not $want"
13101         fi
13102 }
13103
13104 test_133a() {
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106         remote_ost_nodsh && skip "remote OST with nodsh"
13107         remote_mds_nodsh && skip "remote MDS with nodsh"
13108         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13109                 skip_env "MDS doesn't support rename stats"
13110
13111         local testdir=$DIR/${tdir}/stats_testdir
13112
13113         mkdir -p $DIR/${tdir}
13114
13115         # clear stats.
13116         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13117         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13118
13119         # verify mdt stats first.
13120         mkdir ${testdir} || error "mkdir failed"
13121         check_stats $SINGLEMDS "mkdir" 1
13122         touch ${testdir}/${tfile} || error "touch failed"
13123         check_stats $SINGLEMDS "open" 1
13124         check_stats $SINGLEMDS "close" 1
13125         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13126                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13127                 check_stats $SINGLEMDS "mknod" 2
13128         }
13129         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13130         check_stats $SINGLEMDS "unlink" 1
13131         rm -f ${testdir}/${tfile} || error "file remove failed"
13132         check_stats $SINGLEMDS "unlink" 2
13133
13134         # remove working dir and check mdt stats again.
13135         rmdir ${testdir} || error "rmdir failed"
13136         check_stats $SINGLEMDS "rmdir" 1
13137
13138         local testdir1=$DIR/${tdir}/stats_testdir1
13139         mkdir -p ${testdir}
13140         mkdir -p ${testdir1}
13141         touch ${testdir1}/test1
13142         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13143         check_stats $SINGLEMDS "crossdir_rename" 1
13144
13145         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13146         check_stats $SINGLEMDS "samedir_rename" 1
13147
13148         rm -rf $DIR/${tdir}
13149 }
13150 run_test 133a "Verifying MDT stats ========================================"
13151
13152 test_133b() {
13153         local res
13154
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156         remote_ost_nodsh && skip "remote OST with nodsh"
13157         remote_mds_nodsh && skip "remote MDS with nodsh"
13158
13159         local testdir=$DIR/${tdir}/stats_testdir
13160
13161         mkdir -p ${testdir} || error "mkdir failed"
13162         touch ${testdir}/${tfile} || error "touch failed"
13163         cancel_lru_locks mdc
13164
13165         # clear stats.
13166         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13167         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13168
13169         # extra mdt stats verification.
13170         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13171         check_stats $SINGLEMDS "setattr" 1
13172         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13173         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13174         then            # LU-1740
13175                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13176                 check_stats $SINGLEMDS "getattr" 1
13177         fi
13178         rm -rf $DIR/${tdir}
13179
13180         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13181         # so the check below is not reliable
13182         [ $MDSCOUNT -eq 1 ] || return 0
13183
13184         # Sleep to avoid a cached response.
13185         #define OBD_STATFS_CACHE_SECONDS 1
13186         sleep 2
13187         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13188         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13189         $LFS df || error "lfs failed"
13190         check_stats $SINGLEMDS "statfs" 1
13191
13192         # check aggregated statfs (LU-10018)
13193         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13194                 return 0
13195         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13196                 return 0
13197         sleep 2
13198         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13199         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13200         df $DIR
13201         check_stats $SINGLEMDS "statfs" 1
13202
13203         # We want to check that the client didn't send OST_STATFS to
13204         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13205         # extra care is needed here.
13206         if remote_mds; then
13207                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13208                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13209
13210                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13211                 [ "$res" ] && error "OST got STATFS"
13212         fi
13213
13214         return 0
13215 }
13216 run_test 133b "Verifying extra MDT stats =================================="
13217
13218 test_133c() {
13219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13220         remote_ost_nodsh && skip "remote OST with nodsh"
13221         remote_mds_nodsh && skip "remote MDS with nodsh"
13222
13223         local testdir=$DIR/$tdir/stats_testdir
13224
13225         test_mkdir -p $testdir
13226
13227         # verify obdfilter stats.
13228         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13229         sync
13230         cancel_lru_locks osc
13231         wait_delete_completed
13232
13233         # clear stats.
13234         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13235         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13236
13237         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13238                 error "dd failed"
13239         sync
13240         cancel_lru_locks osc
13241         check_stats ost1 "write" 1
13242
13243         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13244         check_stats ost1 "read" 1
13245
13246         > $testdir/$tfile || error "truncate failed"
13247         check_stats ost1 "punch" 1
13248
13249         rm -f $testdir/$tfile || error "file remove failed"
13250         wait_delete_completed
13251         check_stats ost1 "destroy" 1
13252
13253         rm -rf $DIR/$tdir
13254 }
13255 run_test 133c "Verifying OST stats ========================================"
13256
13257 order_2() {
13258         local value=$1
13259         local orig=$value
13260         local order=1
13261
13262         while [ $value -ge 2 ]; do
13263                 order=$((order*2))
13264                 value=$((value/2))
13265         done
13266
13267         if [ $orig -gt $order ]; then
13268                 order=$((order*2))
13269         fi
13270         echo $order
13271 }
13272
13273 size_in_KMGT() {
13274     local value=$1
13275     local size=('K' 'M' 'G' 'T');
13276     local i=0
13277     local size_string=$value
13278
13279     while [ $value -ge 1024 ]; do
13280         if [ $i -gt 3 ]; then
13281             #T is the biggest unit we get here, if that is bigger,
13282             #just return XXXT
13283             size_string=${value}T
13284             break
13285         fi
13286         value=$((value >> 10))
13287         if [ $value -lt 1024 ]; then
13288             size_string=${value}${size[$i]}
13289             break
13290         fi
13291         i=$((i + 1))
13292     done
13293
13294     echo $size_string
13295 }
13296
13297 get_rename_size() {
13298         local size=$1
13299         local context=${2:-.}
13300         local sample=$(do_facet $SINGLEMDS $LCTL \
13301                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13302                 grep -A1 $context |
13303                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13304         echo $sample
13305 }
13306
13307 test_133d() {
13308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13309         remote_ost_nodsh && skip "remote OST with nodsh"
13310         remote_mds_nodsh && skip "remote MDS with nodsh"
13311         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13312                 skip_env "MDS doesn't support rename stats"
13313
13314         local testdir1=$DIR/${tdir}/stats_testdir1
13315         local testdir2=$DIR/${tdir}/stats_testdir2
13316         mkdir -p $DIR/${tdir}
13317
13318         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13319
13320         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13321         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13322
13323         createmany -o $testdir1/test 512 || error "createmany failed"
13324
13325         # check samedir rename size
13326         mv ${testdir1}/test0 ${testdir1}/test_0
13327
13328         local testdir1_size=$(ls -l $DIR/${tdir} |
13329                 awk '/stats_testdir1/ {print $5}')
13330         local testdir2_size=$(ls -l $DIR/${tdir} |
13331                 awk '/stats_testdir2/ {print $5}')
13332
13333         testdir1_size=$(order_2 $testdir1_size)
13334         testdir2_size=$(order_2 $testdir2_size)
13335
13336         testdir1_size=$(size_in_KMGT $testdir1_size)
13337         testdir2_size=$(size_in_KMGT $testdir2_size)
13338
13339         echo "source rename dir size: ${testdir1_size}"
13340         echo "target rename dir size: ${testdir2_size}"
13341
13342         local cmd="do_facet $SINGLEMDS $LCTL "
13343         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13344
13345         eval $cmd || error "$cmd failed"
13346         local samedir=$($cmd | grep 'same_dir')
13347         local same_sample=$(get_rename_size $testdir1_size)
13348         [ -z "$samedir" ] && error "samedir_rename_size count error"
13349         [[ $same_sample -eq 1 ]] ||
13350                 error "samedir_rename_size error $same_sample"
13351         echo "Check same dir rename stats success"
13352
13353         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13354
13355         # check crossdir rename size
13356         mv ${testdir1}/test_0 ${testdir2}/test_0
13357
13358         testdir1_size=$(ls -l $DIR/${tdir} |
13359                 awk '/stats_testdir1/ {print $5}')
13360         testdir2_size=$(ls -l $DIR/${tdir} |
13361                 awk '/stats_testdir2/ {print $5}')
13362
13363         testdir1_size=$(order_2 $testdir1_size)
13364         testdir2_size=$(order_2 $testdir2_size)
13365
13366         testdir1_size=$(size_in_KMGT $testdir1_size)
13367         testdir2_size=$(size_in_KMGT $testdir2_size)
13368
13369         echo "source rename dir size: ${testdir1_size}"
13370         echo "target rename dir size: ${testdir2_size}"
13371
13372         eval $cmd || error "$cmd failed"
13373         local crossdir=$($cmd | grep 'crossdir')
13374         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13375         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13376         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13377         [[ $src_sample -eq 1 ]] ||
13378                 error "crossdir_rename_size error $src_sample"
13379         [[ $tgt_sample -eq 1 ]] ||
13380                 error "crossdir_rename_size error $tgt_sample"
13381         echo "Check cross dir rename stats success"
13382         rm -rf $DIR/${tdir}
13383 }
13384 run_test 133d "Verifying rename_stats ========================================"
13385
13386 test_133e() {
13387         remote_mds_nodsh && skip "remote MDS with nodsh"
13388         remote_ost_nodsh && skip "remote OST with nodsh"
13389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13390
13391         local testdir=$DIR/${tdir}/stats_testdir
13392         local ctr f0 f1 bs=32768 count=42 sum
13393
13394         mkdir -p ${testdir} || error "mkdir failed"
13395
13396         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13397
13398         for ctr in {write,read}_bytes; do
13399                 sync
13400                 cancel_lru_locks osc
13401
13402                 do_facet ost1 $LCTL set_param -n \
13403                         "obdfilter.*.exports.clear=clear"
13404
13405                 if [ $ctr = write_bytes ]; then
13406                         f0=/dev/zero
13407                         f1=${testdir}/${tfile}
13408                 else
13409                         f0=${testdir}/${tfile}
13410                         f1=/dev/null
13411                 fi
13412
13413                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13414                         error "dd failed"
13415                 sync
13416                 cancel_lru_locks osc
13417
13418                 sum=$(do_facet ost1 $LCTL get_param \
13419                         "obdfilter.*.exports.*.stats" |
13420                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13421                                 $1 == ctr { sum += $7 }
13422                                 END { printf("%0.0f", sum) }')
13423
13424                 if ((sum != bs * count)); then
13425                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13426                 fi
13427         done
13428
13429         rm -rf $DIR/${tdir}
13430 }
13431 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13432
13433 test_133f() {
13434         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13435                 skip "too old lustre for get_param -R ($facet_ver)"
13436
13437         # verifying readability.
13438         $LCTL get_param -R '*' &> /dev/null
13439
13440         # Verifing writability with badarea_io.
13441         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13442                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13443                 error "client badarea_io failed"
13444
13445         # remount the FS in case writes/reads /proc break the FS
13446         cleanup || error "failed to unmount"
13447         setup || error "failed to setup"
13448 }
13449 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13450
13451 test_133g() {
13452         remote_mds_nodsh && skip "remote MDS with nodsh"
13453         remote_ost_nodsh && skip "remote OST with nodsh"
13454
13455         local facet
13456         for facet in mds1 ost1; do
13457                 local facet_ver=$(lustre_version_code $facet)
13458                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13459                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13460                 else
13461                         log "$facet: too old lustre for get_param -R"
13462                 fi
13463                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13464                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13465                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13466                                 xargs badarea_io" ||
13467                                         error "$facet badarea_io failed"
13468                 else
13469                         skip_noexit "$facet: too old lustre for get_param -R"
13470                 fi
13471         done
13472
13473         # remount the FS in case writes/reads /proc break the FS
13474         cleanup || error "failed to unmount"
13475         setup || error "failed to setup"
13476 }
13477 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13478
13479 test_133h() {
13480         remote_mds_nodsh && skip "remote MDS with nodsh"
13481         remote_ost_nodsh && skip "remote OST with nodsh"
13482         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13483                 skip "Need MDS version at least 2.9.54"
13484
13485         local facet
13486         for facet in client mds1 ost1; do
13487                 # Get the list of files that are missing the terminating newline
13488                 local plist=$(do_facet $facet
13489                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13490                 local ent
13491                 for ent in $plist; do
13492                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13493                                 awk -v FS='\v' -v RS='\v\v' \
13494                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13495                                         print FILENAME}'" 2>/dev/null)
13496                         [ -z $missing ] || {
13497                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13498                                 error "file does not end with newline: $facet-$ent"
13499                         }
13500                 done
13501         done
13502 }
13503 run_test 133h "Proc files should end with newlines"
13504
13505 test_134a() {
13506         remote_mds_nodsh && skip "remote MDS with nodsh"
13507         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13508                 skip "Need MDS version at least 2.7.54"
13509
13510         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13511         cancel_lru_locks mdc
13512
13513         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13514         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13515         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13516
13517         local nr=1000
13518         createmany -o $DIR/$tdir/f $nr ||
13519                 error "failed to create $nr files in $DIR/$tdir"
13520         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13521
13522         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13523         do_facet mds1 $LCTL set_param fail_loc=0x327
13524         do_facet mds1 $LCTL set_param fail_val=500
13525         touch $DIR/$tdir/m
13526
13527         echo "sleep 10 seconds ..."
13528         sleep 10
13529         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13530
13531         do_facet mds1 $LCTL set_param fail_loc=0
13532         do_facet mds1 $LCTL set_param fail_val=0
13533         [ $lck_cnt -lt $unused ] ||
13534                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13535
13536         rm $DIR/$tdir/m
13537         unlinkmany $DIR/$tdir/f $nr
13538 }
13539 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13540
13541 test_134b() {
13542         remote_mds_nodsh && skip "remote MDS with nodsh"
13543         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13544                 skip "Need MDS version at least 2.7.54"
13545
13546         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13547         cancel_lru_locks mdc
13548
13549         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13550                         ldlm.lock_reclaim_threshold_mb)
13551         # disable reclaim temporarily
13552         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13553
13554         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13555         do_facet mds1 $LCTL set_param fail_loc=0x328
13556         do_facet mds1 $LCTL set_param fail_val=500
13557
13558         $LCTL set_param debug=+trace
13559
13560         local nr=600
13561         createmany -o $DIR/$tdir/f $nr &
13562         local create_pid=$!
13563
13564         echo "Sleep $TIMEOUT seconds ..."
13565         sleep $TIMEOUT
13566         if ! ps -p $create_pid  > /dev/null 2>&1; then
13567                 do_facet mds1 $LCTL set_param fail_loc=0
13568                 do_facet mds1 $LCTL set_param fail_val=0
13569                 do_facet mds1 $LCTL set_param \
13570                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13571                 error "createmany finished incorrectly!"
13572         fi
13573         do_facet mds1 $LCTL set_param fail_loc=0
13574         do_facet mds1 $LCTL set_param fail_val=0
13575         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13576         wait $create_pid || return 1
13577
13578         unlinkmany $DIR/$tdir/f $nr
13579 }
13580 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13581
13582 test_135() {
13583         remote_mds_nodsh && skip "remote MDS with nodsh"
13584         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13585                 skip "Need MDS version at least 2.13.50"
13586         local fname
13587
13588         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13589
13590 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13591         #set only one record at plain llog
13592         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13593
13594         #fill already existed plain llog each 64767
13595         #wrapping whole catalog
13596         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13597
13598         createmany -o $DIR/$tdir/$tfile_ 64700
13599         for (( i = 0; i < 64700; i = i + 2 ))
13600         do
13601                 rm $DIR/$tdir/$tfile_$i &
13602                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13603                 local pid=$!
13604                 wait $pid
13605         done
13606
13607         #waiting osp synchronization
13608         wait_delete_completed
13609 }
13610 run_test 135 "Race catalog processing"
13611
13612 test_136() {
13613         remote_mds_nodsh && skip "remote MDS with nodsh"
13614         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13615                 skip "Need MDS version at least 2.13.50"
13616         local fname
13617
13618         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13619         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13620         #set only one record at plain llog
13621 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13622         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13623
13624         #fill already existed 2 plain llogs each 64767
13625         #wrapping whole catalog
13626         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13627         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13628         wait_delete_completed
13629
13630         createmany -o $DIR/$tdir/$tfile_ 10
13631         sleep 25
13632
13633         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13634         for (( i = 0; i < 10; i = i + 3 ))
13635         do
13636                 rm $DIR/$tdir/$tfile_$i &
13637                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13638                 local pid=$!
13639                 wait $pid
13640                 sleep 7
13641                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13642         done
13643
13644         #waiting osp synchronization
13645         wait_delete_completed
13646 }
13647 run_test 136 "Race catalog processing 2"
13648
13649 test_140() { #bug-17379
13650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13651
13652         test_mkdir $DIR/$tdir
13653         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13654         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13655
13656         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13657         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13658         local i=0
13659         while i=$((i + 1)); do
13660                 test_mkdir $i
13661                 cd $i || error "Changing to $i"
13662                 ln -s ../stat stat || error "Creating stat symlink"
13663                 # Read the symlink until ELOOP present,
13664                 # not LBUGing the system is considered success,
13665                 # we didn't overrun the stack.
13666                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13667                 if [ $ret -ne 0 ]; then
13668                         if [ $ret -eq 40 ]; then
13669                                 break  # -ELOOP
13670                         else
13671                                 error "Open stat symlink"
13672                                         return
13673                         fi
13674                 fi
13675         done
13676         i=$((i - 1))
13677         echo "The symlink depth = $i"
13678         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13679                 error "Invalid symlink depth"
13680
13681         # Test recursive symlink
13682         ln -s symlink_self symlink_self
13683         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13684         echo "open symlink_self returns $ret"
13685         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13686 }
13687 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13688
13689 test_150a() {
13690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13691
13692         local TF="$TMP/$tfile"
13693
13694         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13695         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13696         cp $TF $DIR/$tfile
13697         cancel_lru_locks $OSC
13698         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13699         remount_client $MOUNT
13700         df -P $MOUNT
13701         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13702
13703         $TRUNCATE $TF 6000
13704         $TRUNCATE $DIR/$tfile 6000
13705         cancel_lru_locks $OSC
13706         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13707
13708         echo "12345" >>$TF
13709         echo "12345" >>$DIR/$tfile
13710         cancel_lru_locks $OSC
13711         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13712
13713         echo "12345" >>$TF
13714         echo "12345" >>$DIR/$tfile
13715         cancel_lru_locks $OSC
13716         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13717 }
13718 run_test 150a "truncate/append tests"
13719
13720 test_150b() {
13721         check_set_fallocate_or_skip
13722
13723         touch $DIR/$tfile
13724         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13725         check_fallocate $DIR/$tfile || error "fallocate failed"
13726 }
13727 run_test 150b "Verify fallocate (prealloc) functionality"
13728
13729 test_150bb() {
13730         check_set_fallocate_or_skip
13731
13732         touch $DIR/$tfile
13733         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13734         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13735         > $DIR/$tfile
13736         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13737         # precomputed md5sum for 20MB of zeroes
13738         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13739         local sum=($(md5sum $DIR/$tfile))
13740
13741         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13742
13743         check_set_fallocate 1
13744
13745         > $DIR/$tfile
13746         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13747         sum=($(md5sum $DIR/$tfile))
13748
13749         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13750 }
13751 run_test 150bb "Verify fallocate modes both zero space"
13752
13753 test_150c() {
13754         check_set_fallocate_or_skip
13755
13756         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13757         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13758         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13759         sync; sync_all_data
13760         cancel_lru_locks $OSC
13761         sleep 5
13762         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13763         want=$((OSTCOUNT * 1048576))
13764
13765         # Must allocate all requested space, not more than 5% extra
13766         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13767                 error "bytes $bytes is not $want"
13768
13769         rm -f $DIR/$tfile
13770         # verify fallocate on PFL file
13771         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13772                 error "Create $DIR/$tfile failed"
13773         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13774                         error "fallocate failed"
13775         sync; sync_all_data
13776         cancel_lru_locks $OSC
13777         sleep 5
13778         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13779         local want=$((1024 * 1048576))
13780
13781         # Must allocate all requested space, not more than 5% extra
13782         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13783                 error "bytes $bytes is not $want"
13784 }
13785 run_test 150c "Verify fallocate Size and Blocks"
13786
13787 test_150d() {
13788         check_set_fallocate_or_skip
13789
13790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13791         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13792         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13793         sync; sync_all_data
13794         cancel_lru_locks $OSC
13795         sleep 5
13796         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13797         local want=$((OSTCOUNT * 1048576))
13798
13799         # Must allocate all requested space, not more than 5% extra
13800         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13801                 error "bytes $bytes is not $want"
13802 }
13803 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13804
13805 test_150e() {
13806         check_set_fallocate_or_skip
13807
13808         echo "df before:"
13809         $LFS df
13810         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13811         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13812                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13813
13814         # Find OST with Minimum Size
13815         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13816                        sort -un | head -1)
13817
13818         # Get 100MB per OST of the available space to reduce run time
13819         # else 60% of the available space if we are running SLOW tests
13820         if [ $SLOW == "no" ]; then
13821                 local space=$((1024 * 100 * OSTCOUNT))
13822         else
13823                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13824         fi
13825
13826         fallocate -l${space}k $DIR/$tfile ||
13827                 error "fallocate ${space}k $DIR/$tfile failed"
13828         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13829
13830         # get size immediately after fallocate. This should be correctly
13831         # updated
13832         local size=$(stat -c '%s' $DIR/$tfile)
13833         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13834
13835         # Sleep for a while for statfs to get updated. And not pull from cache.
13836         sleep 2
13837
13838         echo "df after fallocate:"
13839         $LFS df
13840
13841         (( size / 1024 == space )) || error "size $size != requested $space"
13842         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13843                 error "used $used < space $space"
13844
13845         rm $DIR/$tfile || error "rm failed"
13846         sync
13847         wait_delete_completed
13848
13849         echo "df after unlink:"
13850         $LFS df
13851 }
13852 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13853
13854 #LU-2902 roc_hit was not able to read all values from lproc
13855 function roc_hit_init() {
13856         local list=$(comma_list $(osts_nodes))
13857         local dir=$DIR/$tdir-check
13858         local file=$dir/$tfile
13859         local BEFORE
13860         local AFTER
13861         local idx
13862
13863         test_mkdir $dir
13864         #use setstripe to do a write to every ost
13865         for i in $(seq 0 $((OSTCOUNT-1))); do
13866                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13867                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13868                 idx=$(printf %04x $i)
13869                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13870                         awk '$1 == "cache_access" {sum += $7}
13871                                 END { printf("%0.0f", sum) }')
13872
13873                 cancel_lru_locks osc
13874                 cat $file >/dev/null
13875
13876                 AFTER=$(get_osd_param $list *OST*$idx stats |
13877                         awk '$1 == "cache_access" {sum += $7}
13878                                 END { printf("%0.0f", sum) }')
13879
13880                 echo BEFORE:$BEFORE AFTER:$AFTER
13881                 if ! let "AFTER - BEFORE == 4"; then
13882                         rm -rf $dir
13883                         error "roc_hit is not safe to use"
13884                 fi
13885                 rm $file
13886         done
13887
13888         rm -rf $dir
13889 }
13890
13891 function roc_hit() {
13892         local list=$(comma_list $(osts_nodes))
13893         echo $(get_osd_param $list '' stats |
13894                 awk '$1 == "cache_hit" {sum += $7}
13895                         END { printf("%0.0f", sum) }')
13896 }
13897
13898 function set_cache() {
13899         local on=1
13900
13901         if [ "$2" == "off" ]; then
13902                 on=0;
13903         fi
13904         local list=$(comma_list $(osts_nodes))
13905         set_osd_param $list '' $1_cache_enable $on
13906
13907         cancel_lru_locks osc
13908 }
13909
13910 test_151() {
13911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13912         remote_ost_nodsh && skip "remote OST with nodsh"
13913
13914         local CPAGES=3
13915         local list=$(comma_list $(osts_nodes))
13916
13917         # check whether obdfilter is cache capable at all
13918         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13919                 skip "not cache-capable obdfilter"
13920         fi
13921
13922         # check cache is enabled on all obdfilters
13923         if get_osd_param $list '' read_cache_enable | grep 0; then
13924                 skip "oss cache is disabled"
13925         fi
13926
13927         set_osd_param $list '' writethrough_cache_enable 1
13928
13929         # check write cache is enabled on all obdfilters
13930         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13931                 skip "oss write cache is NOT enabled"
13932         fi
13933
13934         roc_hit_init
13935
13936         #define OBD_FAIL_OBD_NO_LRU  0x609
13937         do_nodes $list $LCTL set_param fail_loc=0x609
13938
13939         # pages should be in the case right after write
13940         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13941                 error "dd failed"
13942
13943         local BEFORE=$(roc_hit)
13944         cancel_lru_locks osc
13945         cat $DIR/$tfile >/dev/null
13946         local AFTER=$(roc_hit)
13947
13948         do_nodes $list $LCTL set_param fail_loc=0
13949
13950         if ! let "AFTER - BEFORE == CPAGES"; then
13951                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13952         fi
13953
13954         cancel_lru_locks osc
13955         # invalidates OST cache
13956         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13957         set_osd_param $list '' read_cache_enable 0
13958         cat $DIR/$tfile >/dev/null
13959
13960         # now data shouldn't be found in the cache
13961         BEFORE=$(roc_hit)
13962         cancel_lru_locks osc
13963         cat $DIR/$tfile >/dev/null
13964         AFTER=$(roc_hit)
13965         if let "AFTER - BEFORE != 0"; then
13966                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13967         fi
13968
13969         set_osd_param $list '' read_cache_enable 1
13970         rm -f $DIR/$tfile
13971 }
13972 run_test 151 "test cache on oss and controls ==============================="
13973
13974 test_152() {
13975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13976
13977         local TF="$TMP/$tfile"
13978
13979         # simulate ENOMEM during write
13980 #define OBD_FAIL_OST_NOMEM      0x226
13981         lctl set_param fail_loc=0x80000226
13982         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13983         cp $TF $DIR/$tfile
13984         sync || error "sync failed"
13985         lctl set_param fail_loc=0
13986
13987         # discard client's cache
13988         cancel_lru_locks osc
13989
13990         # simulate ENOMEM during read
13991         lctl set_param fail_loc=0x80000226
13992         cmp $TF $DIR/$tfile || error "cmp failed"
13993         lctl set_param fail_loc=0
13994
13995         rm -f $TF
13996 }
13997 run_test 152 "test read/write with enomem ============================"
13998
13999 test_153() {
14000         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14001 }
14002 run_test 153 "test if fdatasync does not crash ======================="
14003
14004 dot_lustre_fid_permission_check() {
14005         local fid=$1
14006         local ffid=$MOUNT/.lustre/fid/$fid
14007         local test_dir=$2
14008
14009         echo "stat fid $fid"
14010         stat $ffid > /dev/null || error "stat $ffid failed."
14011         echo "touch fid $fid"
14012         touch $ffid || error "touch $ffid failed."
14013         echo "write to fid $fid"
14014         cat /etc/hosts > $ffid || error "write $ffid failed."
14015         echo "read fid $fid"
14016         diff /etc/hosts $ffid || error "read $ffid failed."
14017         echo "append write to fid $fid"
14018         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14019         echo "rename fid $fid"
14020         mv $ffid $test_dir/$tfile.1 &&
14021                 error "rename $ffid to $tfile.1 should fail."
14022         touch $test_dir/$tfile.1
14023         mv $test_dir/$tfile.1 $ffid &&
14024                 error "rename $tfile.1 to $ffid should fail."
14025         rm -f $test_dir/$tfile.1
14026         echo "truncate fid $fid"
14027         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14028         echo "link fid $fid"
14029         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14030         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14031                 echo "setfacl fid $fid"
14032                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14033                 echo "getfacl fid $fid"
14034                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14035         fi
14036         echo "unlink fid $fid"
14037         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14038         echo "mknod fid $fid"
14039         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14040
14041         fid=[0xf00000400:0x1:0x0]
14042         ffid=$MOUNT/.lustre/fid/$fid
14043
14044         echo "stat non-exist fid $fid"
14045         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14046         echo "write to non-exist fid $fid"
14047         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14048         echo "link new fid $fid"
14049         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14050
14051         mkdir -p $test_dir/$tdir
14052         touch $test_dir/$tdir/$tfile
14053         fid=$($LFS path2fid $test_dir/$tdir)
14054         rc=$?
14055         [ $rc -ne 0 ] &&
14056                 error "error: could not get fid for $test_dir/$dir/$tfile."
14057
14058         ffid=$MOUNT/.lustre/fid/$fid
14059
14060         echo "ls $fid"
14061         ls $ffid > /dev/null || error "ls $ffid failed."
14062         echo "touch $fid/$tfile.1"
14063         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14064
14065         echo "touch $MOUNT/.lustre/fid/$tfile"
14066         touch $MOUNT/.lustre/fid/$tfile && \
14067                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14068
14069         echo "setxattr to $MOUNT/.lustre/fid"
14070         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14071
14072         echo "listxattr for $MOUNT/.lustre/fid"
14073         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14074
14075         echo "delxattr from $MOUNT/.lustre/fid"
14076         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14077
14078         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14079         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14080                 error "touch invalid fid should fail."
14081
14082         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14083         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14084                 error "touch non-normal fid should fail."
14085
14086         echo "rename $tdir to $MOUNT/.lustre/fid"
14087         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14088                 error "rename to $MOUNT/.lustre/fid should fail."
14089
14090         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14091         then            # LU-3547
14092                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14093                 local new_obf_mode=777
14094
14095                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14096                 chmod $new_obf_mode $DIR/.lustre/fid ||
14097                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14098
14099                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14100                 [ $obf_mode -eq $new_obf_mode ] ||
14101                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14102
14103                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14104                 chmod $old_obf_mode $DIR/.lustre/fid ||
14105                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14106         fi
14107
14108         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14109         fid=$($LFS path2fid $test_dir/$tfile-2)
14110
14111         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14112         then # LU-5424
14113                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14114                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14115                         error "create lov data thru .lustre failed"
14116         fi
14117         echo "cp /etc/passwd $test_dir/$tfile-2"
14118         cp /etc/passwd $test_dir/$tfile-2 ||
14119                 error "copy to $test_dir/$tfile-2 failed."
14120         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14121         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14122                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14123
14124         rm -rf $test_dir/tfile.lnk
14125         rm -rf $test_dir/$tfile-2
14126 }
14127
14128 test_154A() {
14129         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14130                 skip "Need MDS version at least 2.4.1"
14131
14132         local tf=$DIR/$tfile
14133         touch $tf
14134
14135         local fid=$($LFS path2fid $tf)
14136         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14137
14138         # check that we get the same pathname back
14139         local rootpath
14140         local found
14141         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14142                 echo "$rootpath $fid"
14143                 found=$($LFS fid2path $rootpath "$fid")
14144                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14145                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14146         done
14147
14148         # check wrong root path format
14149         rootpath=$MOUNT"_wrong"
14150         found=$($LFS fid2path $rootpath "$fid")
14151         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14152 }
14153 run_test 154A "lfs path2fid and fid2path basic checks"
14154
14155 test_154B() {
14156         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14157                 skip "Need MDS version at least 2.4.1"
14158
14159         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14160         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14161         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14162         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14163
14164         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14165         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14166
14167         # check that we get the same pathname
14168         echo "PFID: $PFID, name: $name"
14169         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14170         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14171         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14172                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14173
14174         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14175 }
14176 run_test 154B "verify the ll_decode_linkea tool"
14177
14178 test_154a() {
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14181         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14182                 skip "Need MDS version at least 2.2.51"
14183         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14184
14185         cp /etc/hosts $DIR/$tfile
14186
14187         fid=$($LFS path2fid $DIR/$tfile)
14188         rc=$?
14189         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14190
14191         dot_lustre_fid_permission_check "$fid" $DIR ||
14192                 error "dot lustre permission check $fid failed"
14193
14194         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14195
14196         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14197
14198         touch $MOUNT/.lustre/file &&
14199                 error "creation is not allowed under .lustre"
14200
14201         mkdir $MOUNT/.lustre/dir &&
14202                 error "mkdir is not allowed under .lustre"
14203
14204         rm -rf $DIR/$tfile
14205 }
14206 run_test 154a "Open-by-FID"
14207
14208 test_154b() {
14209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14210         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14212         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14213                 skip "Need MDS version at least 2.2.51"
14214
14215         local remote_dir=$DIR/$tdir/remote_dir
14216         local MDTIDX=1
14217         local rc=0
14218
14219         mkdir -p $DIR/$tdir
14220         $LFS mkdir -i $MDTIDX $remote_dir ||
14221                 error "create remote directory failed"
14222
14223         cp /etc/hosts $remote_dir/$tfile
14224
14225         fid=$($LFS path2fid $remote_dir/$tfile)
14226         rc=$?
14227         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14228
14229         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14230                 error "dot lustre permission check $fid failed"
14231         rm -rf $DIR/$tdir
14232 }
14233 run_test 154b "Open-by-FID for remote directory"
14234
14235 test_154c() {
14236         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14237                 skip "Need MDS version at least 2.4.1"
14238
14239         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14240         local FID1=$($LFS path2fid $DIR/$tfile.1)
14241         local FID2=$($LFS path2fid $DIR/$tfile.2)
14242         local FID3=$($LFS path2fid $DIR/$tfile.3)
14243
14244         local N=1
14245         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14246                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14247                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14248                 local want=FID$N
14249                 [ "$FID" = "${!want}" ] ||
14250                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14251                 N=$((N + 1))
14252         done
14253
14254         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14255         do
14256                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14257                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14258                 N=$((N + 1))
14259         done
14260 }
14261 run_test 154c "lfs path2fid and fid2path multiple arguments"
14262
14263 test_154d() {
14264         remote_mds_nodsh && skip "remote MDS with nodsh"
14265         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14266                 skip "Need MDS version at least 2.5.53"
14267
14268         if remote_mds; then
14269                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14270         else
14271                 nid="0@lo"
14272         fi
14273         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14274         local fd
14275         local cmd
14276
14277         rm -f $DIR/$tfile
14278         touch $DIR/$tfile
14279
14280         local fid=$($LFS path2fid $DIR/$tfile)
14281         # Open the file
14282         fd=$(free_fd)
14283         cmd="exec $fd<$DIR/$tfile"
14284         eval $cmd
14285         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14286         echo "$fid_list" | grep "$fid"
14287         rc=$?
14288
14289         cmd="exec $fd>/dev/null"
14290         eval $cmd
14291         if [ $rc -ne 0 ]; then
14292                 error "FID $fid not found in open files list $fid_list"
14293         fi
14294 }
14295 run_test 154d "Verify open file fid"
14296
14297 test_154e()
14298 {
14299         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14300                 skip "Need MDS version at least 2.6.50"
14301
14302         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14303                 error ".lustre returned by readdir"
14304         fi
14305 }
14306 run_test 154e ".lustre is not returned by readdir"
14307
14308 test_154f() {
14309         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14310
14311         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14312         test_mkdir -p -c1 $DIR/$tdir/d
14313         # test dirs inherit from its stripe
14314         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14315         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14316         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14317         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14318         touch $DIR/f
14319
14320         # get fid of parents
14321         local FID0=$($LFS path2fid $DIR/$tdir/d)
14322         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14323         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14324         local FID3=$($LFS path2fid $DIR)
14325
14326         # check that path2fid --parents returns expected <parent_fid>/name
14327         # 1) test for a directory (single parent)
14328         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14329         [ "$parent" == "$FID0/foo1" ] ||
14330                 error "expected parent: $FID0/foo1, got: $parent"
14331
14332         # 2) test for a file with nlink > 1 (multiple parents)
14333         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14334         echo "$parent" | grep -F "$FID1/$tfile" ||
14335                 error "$FID1/$tfile not returned in parent list"
14336         echo "$parent" | grep -F "$FID2/link" ||
14337                 error "$FID2/link not returned in parent list"
14338
14339         # 3) get parent by fid
14340         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14341         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14342         echo "$parent" | grep -F "$FID1/$tfile" ||
14343                 error "$FID1/$tfile not returned in parent list (by fid)"
14344         echo "$parent" | grep -F "$FID2/link" ||
14345                 error "$FID2/link not returned in parent list (by fid)"
14346
14347         # 4) test for entry in root directory
14348         parent=$($LFS path2fid --parents $DIR/f)
14349         echo "$parent" | grep -F "$FID3/f" ||
14350                 error "$FID3/f not returned in parent list"
14351
14352         # 5) test it on root directory
14353         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14354                 error "$MOUNT should not have parents"
14355
14356         # enable xattr caching and check that linkea is correctly updated
14357         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14358         save_lustre_params client "llite.*.xattr_cache" > $save
14359         lctl set_param llite.*.xattr_cache 1
14360
14361         # 6.1) linkea update on rename
14362         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14363
14364         # get parents by fid
14365         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14366         # foo1 should no longer be returned in parent list
14367         echo "$parent" | grep -F "$FID1" &&
14368                 error "$FID1 should no longer be in parent list"
14369         # the new path should appear
14370         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14371                 error "$FID2/$tfile.moved is not in parent list"
14372
14373         # 6.2) linkea update on unlink
14374         rm -f $DIR/$tdir/d/foo2/link
14375         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14376         # foo2/link should no longer be returned in parent list
14377         echo "$parent" | grep -F "$FID2/link" &&
14378                 error "$FID2/link should no longer be in parent list"
14379         true
14380
14381         rm -f $DIR/f
14382         restore_lustre_params < $save
14383         rm -f $save
14384 }
14385 run_test 154f "get parent fids by reading link ea"
14386
14387 test_154g()
14388 {
14389         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14390         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14391            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14392                 skip "Need MDS version at least 2.6.92"
14393
14394         mkdir -p $DIR/$tdir
14395         llapi_fid_test -d $DIR/$tdir
14396 }
14397 run_test 154g "various llapi FID tests"
14398
14399 test_155_small_load() {
14400     local temp=$TMP/$tfile
14401     local file=$DIR/$tfile
14402
14403     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14404         error "dd of=$temp bs=6096 count=1 failed"
14405     cp $temp $file
14406     cancel_lru_locks $OSC
14407     cmp $temp $file || error "$temp $file differ"
14408
14409     $TRUNCATE $temp 6000
14410     $TRUNCATE $file 6000
14411     cmp $temp $file || error "$temp $file differ (truncate1)"
14412
14413     echo "12345" >>$temp
14414     echo "12345" >>$file
14415     cmp $temp $file || error "$temp $file differ (append1)"
14416
14417     echo "12345" >>$temp
14418     echo "12345" >>$file
14419     cmp $temp $file || error "$temp $file differ (append2)"
14420
14421     rm -f $temp $file
14422     true
14423 }
14424
14425 test_155_big_load() {
14426         remote_ost_nodsh && skip "remote OST with nodsh"
14427
14428         local temp=$TMP/$tfile
14429         local file=$DIR/$tfile
14430
14431         free_min_max
14432         local cache_size=$(do_facet ost$((MAXI+1)) \
14433                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14434         local large_file_size=$((cache_size * 2))
14435
14436         echo "OSS cache size: $cache_size KB"
14437         echo "Large file size: $large_file_size KB"
14438
14439         [ $MAXV -le $large_file_size ] &&
14440                 skip_env "max available OST size needs > $large_file_size KB"
14441
14442         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14443
14444         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14445                 error "dd of=$temp bs=$large_file_size count=1k failed"
14446         cp $temp $file
14447         ls -lh $temp $file
14448         cancel_lru_locks osc
14449         cmp $temp $file || error "$temp $file differ"
14450
14451         rm -f $temp $file
14452         true
14453 }
14454
14455 save_writethrough() {
14456         local facets=$(get_facets OST)
14457
14458         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14459 }
14460
14461 test_155a() {
14462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14463
14464         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14465
14466         save_writethrough $p
14467
14468         set_cache read on
14469         set_cache writethrough on
14470         test_155_small_load
14471         restore_lustre_params < $p
14472         rm -f $p
14473 }
14474 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14475
14476 test_155b() {
14477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14478
14479         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14480
14481         save_writethrough $p
14482
14483         set_cache read on
14484         set_cache writethrough off
14485         test_155_small_load
14486         restore_lustre_params < $p
14487         rm -f $p
14488 }
14489 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14490
14491 test_155c() {
14492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14493
14494         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14495
14496         save_writethrough $p
14497
14498         set_cache read off
14499         set_cache writethrough on
14500         test_155_small_load
14501         restore_lustre_params < $p
14502         rm -f $p
14503 }
14504 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14505
14506 test_155d() {
14507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14508
14509         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14510
14511         save_writethrough $p
14512
14513         set_cache read off
14514         set_cache writethrough off
14515         test_155_small_load
14516         restore_lustre_params < $p
14517         rm -f $p
14518 }
14519 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14520
14521 test_155e() {
14522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14523
14524         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14525
14526         save_writethrough $p
14527
14528         set_cache read on
14529         set_cache writethrough on
14530         test_155_big_load
14531         restore_lustre_params < $p
14532         rm -f $p
14533 }
14534 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14535
14536 test_155f() {
14537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14538
14539         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14540
14541         save_writethrough $p
14542
14543         set_cache read on
14544         set_cache writethrough off
14545         test_155_big_load
14546         restore_lustre_params < $p
14547         rm -f $p
14548 }
14549 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14550
14551 test_155g() {
14552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14553
14554         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14555
14556         save_writethrough $p
14557
14558         set_cache read off
14559         set_cache writethrough on
14560         test_155_big_load
14561         restore_lustre_params < $p
14562         rm -f $p
14563 }
14564 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14565
14566 test_155h() {
14567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14568
14569         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14570
14571         save_writethrough $p
14572
14573         set_cache read off
14574         set_cache writethrough off
14575         test_155_big_load
14576         restore_lustre_params < $p
14577         rm -f $p
14578 }
14579 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14580
14581 test_156() {
14582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14583         remote_ost_nodsh && skip "remote OST with nodsh"
14584         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14585                 skip "stats not implemented on old servers"
14586         [ "$ost1_FSTYPE" = "zfs" ] &&
14587                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14588
14589         local CPAGES=3
14590         local BEFORE
14591         local AFTER
14592         local file="$DIR/$tfile"
14593         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14594
14595         save_writethrough $p
14596         roc_hit_init
14597
14598         log "Turn on read and write cache"
14599         set_cache read on
14600         set_cache writethrough on
14601
14602         log "Write data and read it back."
14603         log "Read should be satisfied from the cache."
14604         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14605         BEFORE=$(roc_hit)
14606         cancel_lru_locks osc
14607         cat $file >/dev/null
14608         AFTER=$(roc_hit)
14609         if ! let "AFTER - BEFORE == CPAGES"; then
14610                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14611         else
14612                 log "cache hits: before: $BEFORE, after: $AFTER"
14613         fi
14614
14615         log "Read again; it should be satisfied from the cache."
14616         BEFORE=$AFTER
14617         cancel_lru_locks osc
14618         cat $file >/dev/null
14619         AFTER=$(roc_hit)
14620         if ! let "AFTER - BEFORE == CPAGES"; then
14621                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14622         else
14623                 log "cache hits:: before: $BEFORE, after: $AFTER"
14624         fi
14625
14626         log "Turn off the read cache and turn on the write cache"
14627         set_cache read off
14628         set_cache writethrough on
14629
14630         log "Read again; it should be satisfied from the cache."
14631         BEFORE=$(roc_hit)
14632         cancel_lru_locks osc
14633         cat $file >/dev/null
14634         AFTER=$(roc_hit)
14635         if ! let "AFTER - BEFORE == CPAGES"; then
14636                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14637         else
14638                 log "cache hits:: before: $BEFORE, after: $AFTER"
14639         fi
14640
14641         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14642                 # > 2.12.56 uses pagecache if cached
14643                 log "Read again; it should not be satisfied from the cache."
14644                 BEFORE=$AFTER
14645                 cancel_lru_locks osc
14646                 cat $file >/dev/null
14647                 AFTER=$(roc_hit)
14648                 if ! let "AFTER - BEFORE == 0"; then
14649                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14650                 else
14651                         log "cache hits:: before: $BEFORE, after: $AFTER"
14652                 fi
14653         fi
14654
14655         log "Write data and read it back."
14656         log "Read should be satisfied from the cache."
14657         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14658         BEFORE=$(roc_hit)
14659         cancel_lru_locks osc
14660         cat $file >/dev/null
14661         AFTER=$(roc_hit)
14662         if ! let "AFTER - BEFORE == CPAGES"; then
14663                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14664         else
14665                 log "cache hits:: before: $BEFORE, after: $AFTER"
14666         fi
14667
14668         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14669                 # > 2.12.56 uses pagecache if cached
14670                 log "Read again; it should not be satisfied from the cache."
14671                 BEFORE=$AFTER
14672                 cancel_lru_locks osc
14673                 cat $file >/dev/null
14674                 AFTER=$(roc_hit)
14675                 if ! let "AFTER - BEFORE == 0"; then
14676                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14677                 else
14678                         log "cache hits:: before: $BEFORE, after: $AFTER"
14679                 fi
14680         fi
14681
14682         log "Turn off read and write cache"
14683         set_cache read off
14684         set_cache writethrough off
14685
14686         log "Write data and read it back"
14687         log "It should not be satisfied from the cache."
14688         rm -f $file
14689         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14690         cancel_lru_locks osc
14691         BEFORE=$(roc_hit)
14692         cat $file >/dev/null
14693         AFTER=$(roc_hit)
14694         if ! let "AFTER - BEFORE == 0"; then
14695                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14696         else
14697                 log "cache hits:: before: $BEFORE, after: $AFTER"
14698         fi
14699
14700         log "Turn on the read cache and turn off the write cache"
14701         set_cache read on
14702         set_cache writethrough off
14703
14704         log "Write data and read it back"
14705         log "It should not be satisfied from the cache."
14706         rm -f $file
14707         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14708         BEFORE=$(roc_hit)
14709         cancel_lru_locks osc
14710         cat $file >/dev/null
14711         AFTER=$(roc_hit)
14712         if ! let "AFTER - BEFORE == 0"; then
14713                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14714         else
14715                 log "cache hits:: before: $BEFORE, after: $AFTER"
14716         fi
14717
14718         log "Read again; it should be satisfied from the cache."
14719         BEFORE=$(roc_hit)
14720         cancel_lru_locks osc
14721         cat $file >/dev/null
14722         AFTER=$(roc_hit)
14723         if ! let "AFTER - BEFORE == CPAGES"; then
14724                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14725         else
14726                 log "cache hits:: before: $BEFORE, after: $AFTER"
14727         fi
14728
14729         restore_lustre_params < $p
14730         rm -f $p $file
14731 }
14732 run_test 156 "Verification of tunables"
14733
14734 test_160a() {
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736         remote_mds_nodsh && skip "remote MDS with nodsh"
14737         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14738                 skip "Need MDS version at least 2.2.0"
14739
14740         changelog_register || error "changelog_register failed"
14741         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14742         changelog_users $SINGLEMDS | grep -q $cl_user ||
14743                 error "User $cl_user not found in changelog_users"
14744
14745         # change something
14746         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14747         changelog_clear 0 || error "changelog_clear failed"
14748         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14749         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14750         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14751         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14752         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14753         rm $DIR/$tdir/pics/desktop.jpg
14754
14755         changelog_dump | tail -10
14756
14757         echo "verifying changelog mask"
14758         changelog_chmask "-MKDIR"
14759         changelog_chmask "-CLOSE"
14760
14761         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14762         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14763
14764         changelog_chmask "+MKDIR"
14765         changelog_chmask "+CLOSE"
14766
14767         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14768         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14769
14770         changelog_dump | tail -10
14771         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14772         CLOSES=$(changelog_dump | grep -c "CLOSE")
14773         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14774         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14775
14776         # verify contents
14777         echo "verifying target fid"
14778         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14779         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14780         [ "$fidc" == "$fidf" ] ||
14781                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14782         echo "verifying parent fid"
14783         # The FID returned from the Changelog may be the directory shard on
14784         # a different MDT, and not the FID returned by path2fid on the parent.
14785         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14786         # since this is what will matter when recreating this file in the tree.
14787         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14788         local pathp=$($LFS fid2path $MOUNT "$fidp")
14789         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14790                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14791
14792         echo "getting records for $cl_user"
14793         changelog_users $SINGLEMDS
14794         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14795         local nclr=3
14796         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14797                 error "changelog_clear failed"
14798         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14799         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14800         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14801                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14802
14803         local min0_rec=$(changelog_users $SINGLEMDS |
14804                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14805         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14806                           awk '{ print $1; exit; }')
14807
14808         changelog_dump | tail -n 5
14809         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14810         [ $first_rec == $((min0_rec + 1)) ] ||
14811                 error "first index should be $min0_rec + 1 not $first_rec"
14812
14813         # LU-3446 changelog index reset on MDT restart
14814         local cur_rec1=$(changelog_users $SINGLEMDS |
14815                          awk '/^current.index:/ { print $NF }')
14816         changelog_clear 0 ||
14817                 error "clear all changelog records for $cl_user failed"
14818         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14819         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14820                 error "Fail to start $SINGLEMDS"
14821         local cur_rec2=$(changelog_users $SINGLEMDS |
14822                          awk '/^current.index:/ { print $NF }')
14823         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14824         [ $cur_rec1 == $cur_rec2 ] ||
14825                 error "current index should be $cur_rec1 not $cur_rec2"
14826
14827         echo "verifying users from this test are deregistered"
14828         changelog_deregister || error "changelog_deregister failed"
14829         changelog_users $SINGLEMDS | grep -q $cl_user &&
14830                 error "User '$cl_user' still in changelog_users"
14831
14832         # lctl get_param -n mdd.*.changelog_users
14833         # current index: 144
14834         # ID    index (idle seconds)
14835         # cl3   144 (2)
14836         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14837                 # this is the normal case where all users were deregistered
14838                 # make sure no new records are added when no users are present
14839                 local last_rec1=$(changelog_users $SINGLEMDS |
14840                                   awk '/^current.index:/ { print $NF }')
14841                 touch $DIR/$tdir/chloe
14842                 local last_rec2=$(changelog_users $SINGLEMDS |
14843                                   awk '/^current.index:/ { print $NF }')
14844                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14845                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14846         else
14847                 # any changelog users must be leftovers from a previous test
14848                 changelog_users $SINGLEMDS
14849                 echo "other changelog users; can't verify off"
14850         fi
14851 }
14852 run_test 160a "changelog sanity"
14853
14854 test_160b() { # LU-3587
14855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14856         remote_mds_nodsh && skip "remote MDS with nodsh"
14857         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14858                 skip "Need MDS version at least 2.2.0"
14859
14860         changelog_register || error "changelog_register failed"
14861         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14862         changelog_users $SINGLEMDS | grep -q $cl_user ||
14863                 error "User '$cl_user' not found in changelog_users"
14864
14865         local longname1=$(str_repeat a 255)
14866         local longname2=$(str_repeat b 255)
14867
14868         cd $DIR
14869         echo "creating very long named file"
14870         touch $longname1 || error "create of '$longname1' failed"
14871         echo "renaming very long named file"
14872         mv $longname1 $longname2
14873
14874         changelog_dump | grep RENME | tail -n 5
14875         rm -f $longname2
14876 }
14877 run_test 160b "Verify that very long rename doesn't crash in changelog"
14878
14879 test_160c() {
14880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14881         remote_mds_nodsh && skip "remote MDS with nodsh"
14882
14883         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14884                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14885                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14886                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14887
14888         local rc=0
14889
14890         # Registration step
14891         changelog_register || error "changelog_register failed"
14892
14893         rm -rf $DIR/$tdir
14894         mkdir -p $DIR/$tdir
14895         $MCREATE $DIR/$tdir/foo_160c
14896         changelog_chmask "-TRUNC"
14897         $TRUNCATE $DIR/$tdir/foo_160c 200
14898         changelog_chmask "+TRUNC"
14899         $TRUNCATE $DIR/$tdir/foo_160c 199
14900         changelog_dump | tail -n 5
14901         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14902         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14903 }
14904 run_test 160c "verify that changelog log catch the truncate event"
14905
14906 test_160d() {
14907         remote_mds_nodsh && skip "remote MDS with nodsh"
14908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14910         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14911                 skip "Need MDS version at least 2.7.60"
14912
14913         # Registration step
14914         changelog_register || error "changelog_register failed"
14915
14916         mkdir -p $DIR/$tdir/migrate_dir
14917         changelog_clear 0 || error "changelog_clear failed"
14918
14919         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14920         changelog_dump | tail -n 5
14921         local migrates=$(changelog_dump | grep -c "MIGRT")
14922         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14923 }
14924 run_test 160d "verify that changelog log catch the migrate event"
14925
14926 test_160e() {
14927         remote_mds_nodsh && skip "remote MDS with nodsh"
14928
14929         # Create a user
14930         changelog_register || error "changelog_register failed"
14931
14932         # Delete a future user (expect fail)
14933         local MDT0=$(facet_svc $SINGLEMDS)
14934         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14935         local rc=$?
14936
14937         if [ $rc -eq 0 ]; then
14938                 error "Deleted non-existant user cl77"
14939         elif [ $rc -ne 2 ]; then
14940                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14941         fi
14942
14943         # Clear to a bad index (1 billion should be safe)
14944         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14945         rc=$?
14946
14947         if [ $rc -eq 0 ]; then
14948                 error "Successfully cleared to invalid CL index"
14949         elif [ $rc -ne 22 ]; then
14950                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14951         fi
14952 }
14953 run_test 160e "changelog negative testing (should return errors)"
14954
14955 test_160f() {
14956         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14957         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14958                 skip "Need MDS version at least 2.10.56"
14959
14960         local mdts=$(comma_list $(mdts_nodes))
14961
14962         # Create a user
14963         changelog_register || error "first changelog_register failed"
14964         changelog_register || error "second changelog_register failed"
14965         local cl_users
14966         declare -A cl_user1
14967         declare -A cl_user2
14968         local user_rec1
14969         local user_rec2
14970         local i
14971
14972         # generate some changelog records to accumulate on each MDT
14973         # use all_char because created files should be evenly distributed
14974         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
14975                 error "test_mkdir $tdir failed"
14976         log "$(date +%s): creating first files"
14977         for ((i = 0; i < MDSCOUNT * 2; i++)); do
14978                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
14979                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
14980         done
14981
14982         # check changelogs have been generated
14983         local start=$SECONDS
14984         local idle_time=$((MDSCOUNT * 5 + 5))
14985         local nbcl=$(changelog_dump | wc -l)
14986         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14987
14988         for param in "changelog_max_idle_time=$idle_time" \
14989                      "changelog_gc=1" \
14990                      "changelog_min_gc_interval=2" \
14991                      "changelog_min_free_cat_entries=3"; do
14992                 local MDT0=$(facet_svc $SINGLEMDS)
14993                 local var="${param%=*}"
14994                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14995
14996                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14997                 do_nodes $mdts $LCTL set_param mdd.*.$param
14998         done
14999
15000         # force cl_user2 to be idle (1st part), but also cancel the
15001         # cl_user1 records so that it is not evicted later in the test.
15002         local sleep1=$((idle_time / 2))
15003         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15004         sleep $sleep1
15005
15006         # simulate changelog catalog almost full
15007         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15008         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15009
15010         for i in $(seq $MDSCOUNT); do
15011                 cl_users=(${CL_USERS[mds$i]})
15012                 cl_user1[mds$i]="${cl_users[0]}"
15013                 cl_user2[mds$i]="${cl_users[1]}"
15014
15015                 [ -n "${cl_user1[mds$i]}" ] ||
15016                         error "mds$i: no user registered"
15017                 [ -n "${cl_user2[mds$i]}" ] ||
15018                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15019
15020                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15021                 [ -n "$user_rec1" ] ||
15022                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15023                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15024                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15025                 [ -n "$user_rec2" ] ||
15026                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15027                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15028                      "$user_rec1 + 2 == $user_rec2"
15029                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15030                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15031                               "$user_rec1 + 2, but is $user_rec2"
15032                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15033                 [ -n "$user_rec2" ] ||
15034                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15035                 [ $user_rec1 == $user_rec2 ] ||
15036                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15037                               "$user_rec1, but is $user_rec2"
15038         done
15039
15040         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15041         local sleep2=$((idle_time - (SECONDS - start) + 1))
15042         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15043         sleep $sleep2
15044
15045         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15046         # cl_user1 should be OK because it recently processed records.
15047         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15048         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15049                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15050                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15051         done
15052
15053         # ensure gc thread is done
15054         for i in $(mdts_nodes); do
15055                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15056                         error "$i: GC-thread not done"
15057         done
15058
15059         local first_rec
15060         for (( i = 1; i <= MDSCOUNT; i++ )); do
15061                 # check cl_user1 still registered
15062                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15063                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15064                 # check cl_user2 unregistered
15065                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15066                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15067
15068                 # check changelogs are present and starting at $user_rec1 + 1
15069                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15070                 [ -n "$user_rec1" ] ||
15071                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15072                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15073                             awk '{ print $1; exit; }')
15074
15075                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15076                 [ $((user_rec1 + 1)) == $first_rec ] ||
15077                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15078         done
15079 }
15080 run_test 160f "changelog garbage collect (timestamped users)"
15081
15082 test_160g() {
15083         remote_mds_nodsh && skip "remote MDS with nodsh"
15084         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15085                 skip "Need MDS version at least 2.10.56"
15086
15087         local mdts=$(comma_list $(mdts_nodes))
15088
15089         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15090         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15091
15092         # Create a user
15093         changelog_register || error "first changelog_register failed"
15094         changelog_register || error "second changelog_register failed"
15095         local cl_users
15096         declare -A cl_user1
15097         declare -A cl_user2
15098         local user_rec1
15099         local user_rec2
15100         local i
15101
15102         # generate some changelog records to accumulate on each MDT
15103         # use all_char because created files should be evenly distributed
15104         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15105                 error "test_mkdir $tdir failed"
15106         for ((i = 0; i < MDSCOUNT; i++)); do
15107                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15108                         error "create $DIR/$tdir/d$i.1 failed"
15109         done
15110
15111         # check changelogs have been generated
15112         local nbcl=$(changelog_dump | wc -l)
15113         (( $nbcl > 0 )) || error "no changelogs found"
15114
15115         # reduce the max_idle_indexes value to make sure we exceed it
15116         for param in "changelog_max_idle_indexes=1" \
15117                      "changelog_gc=1" \
15118                      "changelog_min_gc_interval=2" \
15119                      "changelog_min_free_cat_entries=3"; do
15120                 local MDT0=$(facet_svc $SINGLEMDS)
15121                 local var="${param%=*}"
15122                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15123
15124                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15125                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15126                         error "unable to set mdd.*.$param"
15127         done
15128
15129         # simulate changelog catalog almost full
15130         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15131         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15132
15133         local start=$SECONDS
15134         for i in $(seq $MDSCOUNT); do
15135                 cl_users=(${CL_USERS[mds$i]})
15136                 cl_user1[mds$i]="${cl_users[0]}"
15137                 cl_user2[mds$i]="${cl_users[1]}"
15138
15139                 [ -n "${cl_user1[mds$i]}" ] ||
15140                         error "mds$i: no user registered"
15141                 [ -n "${cl_user2[mds$i]}" ] ||
15142                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15143
15144                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15145                 [ -n "$user_rec1" ] ||
15146                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15147                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15148                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15149                 [ -n "$user_rec2" ] ||
15150                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15151                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15152                      "$user_rec1 + 2 == $user_rec2"
15153                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15154                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15155                               "$user_rec1 + 2, but is $user_rec2"
15156                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15157                 [ -n "$user_rec2" ] ||
15158                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15159                 [ $user_rec1 == $user_rec2 ] ||
15160                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15161                               "$user_rec1, but is $user_rec2"
15162         done
15163
15164         # ensure we are past the previous changelog_min_gc_interval set above
15165         local sleep2=$((start + 2 - SECONDS))
15166         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15167
15168         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15169         # cl_user1 should be OK because it recently processed records.
15170         for ((i = 0; i < MDSCOUNT; i++)); do
15171                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15172                         error "create $DIR/$tdir/d$i.3 failed"
15173         done
15174
15175         # ensure gc thread is done
15176         for i in $(mdts_nodes); do
15177                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15178                         error "$i: GC-thread not done"
15179         done
15180
15181         local first_rec
15182         for (( i = 1; i <= MDSCOUNT; i++ )); do
15183                 # check cl_user1 still registered
15184                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15185                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15186                 # check cl_user2 unregistered
15187                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15188                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15189
15190                 # check changelogs are present and starting at $user_rec1 + 1
15191                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15192                 [ -n "$user_rec1" ] ||
15193                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15194                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15195                             awk '{ print $1; exit; }')
15196
15197                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15198                 [ $((user_rec1 + 1)) == $first_rec ] ||
15199                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15200         done
15201 }
15202 run_test 160g "changelog garbage collect (old users)"
15203
15204 test_160h() {
15205         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15206         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15207                 skip "Need MDS version at least 2.10.56"
15208
15209         local mdts=$(comma_list $(mdts_nodes))
15210
15211         # Create a user
15212         changelog_register || error "first changelog_register failed"
15213         changelog_register || error "second changelog_register failed"
15214         local cl_users
15215         declare -A cl_user1
15216         declare -A cl_user2
15217         local user_rec1
15218         local user_rec2
15219         local i
15220
15221         # generate some changelog records to accumulate on each MDT
15222         # use all_char because created files should be evenly distributed
15223         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15224                 error "test_mkdir $tdir failed"
15225         for ((i = 0; i < MDSCOUNT; i++)); do
15226                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15227                         error "create $DIR/$tdir/d$i.1 failed"
15228         done
15229
15230         # check changelogs have been generated
15231         local nbcl=$(changelog_dump | wc -l)
15232         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15233
15234         for param in "changelog_max_idle_time=10" \
15235                      "changelog_gc=1" \
15236                      "changelog_min_gc_interval=2"; do
15237                 local MDT0=$(facet_svc $SINGLEMDS)
15238                 local var="${param%=*}"
15239                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15240
15241                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15242                 do_nodes $mdts $LCTL set_param mdd.*.$param
15243         done
15244
15245         # force cl_user2 to be idle (1st part)
15246         sleep 9
15247
15248         for i in $(seq $MDSCOUNT); do
15249                 cl_users=(${CL_USERS[mds$i]})
15250                 cl_user1[mds$i]="${cl_users[0]}"
15251                 cl_user2[mds$i]="${cl_users[1]}"
15252
15253                 [ -n "${cl_user1[mds$i]}" ] ||
15254                         error "mds$i: no user registered"
15255                 [ -n "${cl_user2[mds$i]}" ] ||
15256                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15257
15258                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15259                 [ -n "$user_rec1" ] ||
15260                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15261                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15262                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15263                 [ -n "$user_rec2" ] ||
15264                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15265                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15266                      "$user_rec1 + 2 == $user_rec2"
15267                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15268                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15269                               "$user_rec1 + 2, but is $user_rec2"
15270                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15271                 [ -n "$user_rec2" ] ||
15272                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15273                 [ $user_rec1 == $user_rec2 ] ||
15274                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15275                               "$user_rec1, but is $user_rec2"
15276         done
15277
15278         # force cl_user2 to be idle (2nd part) and to reach
15279         # changelog_max_idle_time
15280         sleep 2
15281
15282         # force each GC-thread start and block then
15283         # one per MDT/MDD, set fail_val accordingly
15284         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15285         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15286
15287         # generate more changelogs to trigger fail_loc
15288         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15289                 error "create $DIR/$tdir/${tfile}bis failed"
15290
15291         # stop MDT to stop GC-thread, should be done in back-ground as it will
15292         # block waiting for the thread to be released and exit
15293         declare -A stop_pids
15294         for i in $(seq $MDSCOUNT); do
15295                 stop mds$i &
15296                 stop_pids[mds$i]=$!
15297         done
15298
15299         for i in $(mdts_nodes); do
15300                 local facet
15301                 local nb=0
15302                 local facets=$(facets_up_on_host $i)
15303
15304                 for facet in ${facets//,/ }; do
15305                         if [[ $facet == mds* ]]; then
15306                                 nb=$((nb + 1))
15307                         fi
15308                 done
15309                 # ensure each MDS's gc threads are still present and all in "R"
15310                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15311                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15312                         error "$i: expected $nb GC-thread"
15313                 wait_update $i \
15314                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15315                         "R" 20 ||
15316                         error "$i: GC-thread not found in R-state"
15317                 # check umounts of each MDT on MDS have reached kthread_stop()
15318                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15319                         error "$i: expected $nb umount"
15320                 wait_update $i \
15321                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15322                         error "$i: umount not found in D-state"
15323         done
15324
15325         # release all GC-threads
15326         do_nodes $mdts $LCTL set_param fail_loc=0
15327
15328         # wait for MDT stop to complete
15329         for i in $(seq $MDSCOUNT); do
15330                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15331         done
15332
15333         # XXX
15334         # may try to check if any orphan changelog records are present
15335         # via ldiskfs/zfs and llog_reader...
15336
15337         # re-start/mount MDTs
15338         for i in $(seq $MDSCOUNT); do
15339                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15340                         error "Fail to start mds$i"
15341         done
15342
15343         local first_rec
15344         for i in $(seq $MDSCOUNT); do
15345                 # check cl_user1 still registered
15346                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15347                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15348                 # check cl_user2 unregistered
15349                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15350                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15351
15352                 # check changelogs are present and starting at $user_rec1 + 1
15353                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15354                 [ -n "$user_rec1" ] ||
15355                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15356                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15357                             awk '{ print $1; exit; }')
15358
15359                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15360                 [ $((user_rec1 + 1)) == $first_rec ] ||
15361                         error "mds$i: first index should be $user_rec1 + 1, " \
15362                               "but is $first_rec"
15363         done
15364 }
15365 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15366               "during mount"
15367
15368 test_160i() {
15369
15370         local mdts=$(comma_list $(mdts_nodes))
15371
15372         changelog_register || error "first changelog_register failed"
15373
15374         # generate some changelog records to accumulate on each MDT
15375         # use all_char because created files should be evenly distributed
15376         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15377                 error "test_mkdir $tdir failed"
15378         for ((i = 0; i < MDSCOUNT; i++)); do
15379                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15380                         error "create $DIR/$tdir/d$i.1 failed"
15381         done
15382
15383         # check changelogs have been generated
15384         local nbcl=$(changelog_dump | wc -l)
15385         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15386
15387         # simulate race between register and unregister
15388         # XXX as fail_loc is set per-MDS, with DNE configs the race
15389         # simulation will only occur for one MDT per MDS and for the
15390         # others the normal race scenario will take place
15391         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15392         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15393         do_nodes $mdts $LCTL set_param fail_val=1
15394
15395         # unregister 1st user
15396         changelog_deregister &
15397         local pid1=$!
15398         # wait some time for deregister work to reach race rdv
15399         sleep 2
15400         # register 2nd user
15401         changelog_register || error "2nd user register failed"
15402
15403         wait $pid1 || error "1st user deregister failed"
15404
15405         local i
15406         local last_rec
15407         declare -A LAST_REC
15408         for i in $(seq $MDSCOUNT); do
15409                 if changelog_users mds$i | grep "^cl"; then
15410                         # make sure new records are added with one user present
15411                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15412                                           awk '/^current.index:/ { print $NF }')
15413                 else
15414                         error "mds$i has no user registered"
15415                 fi
15416         done
15417
15418         # generate more changelog records to accumulate on each MDT
15419         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15420                 error "create $DIR/$tdir/${tfile}bis failed"
15421
15422         for i in $(seq $MDSCOUNT); do
15423                 last_rec=$(changelog_users $SINGLEMDS |
15424                            awk '/^current.index:/ { print $NF }')
15425                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15426                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15427                         error "changelogs are off on mds$i"
15428         done
15429 }
15430 run_test 160i "changelog user register/unregister race"
15431
15432 test_160j() {
15433         remote_mds_nodsh && skip "remote MDS with nodsh"
15434         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15435                 skip "Need MDS version at least 2.12.56"
15436
15437         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15438         stack_trap "umount $MOUNT2" EXIT
15439
15440         changelog_register || error "first changelog_register failed"
15441         stack_trap "changelog_deregister" EXIT
15442
15443         # generate some changelog
15444         # use all_char because created files should be evenly distributed
15445         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15446                 error "mkdir $tdir failed"
15447         for ((i = 0; i < MDSCOUNT; i++)); do
15448                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15449                         error "create $DIR/$tdir/d$i.1 failed"
15450         done
15451
15452         # open the changelog device
15453         exec 3>/dev/changelog-$FSNAME-MDT0000
15454         stack_trap "exec 3>&-" EXIT
15455         exec 4</dev/changelog-$FSNAME-MDT0000
15456         stack_trap "exec 4<&-" EXIT
15457
15458         # umount the first lustre mount
15459         umount $MOUNT
15460         stack_trap "mount_client $MOUNT" EXIT
15461
15462         # read changelog, which may or may not fail, but should not crash
15463         cat <&4 >/dev/null
15464
15465         # clear changelog
15466         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15467         changelog_users $SINGLEMDS | grep -q $cl_user ||
15468                 error "User $cl_user not found in changelog_users"
15469
15470         printf 'clear:'$cl_user':0' >&3
15471 }
15472 run_test 160j "client can be umounted while its chanangelog is being used"
15473
15474 test_160k() {
15475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15476         remote_mds_nodsh && skip "remote MDS with nodsh"
15477
15478         mkdir -p $DIR/$tdir/1/1
15479
15480         changelog_register || error "changelog_register failed"
15481         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15482
15483         changelog_users $SINGLEMDS | grep -q $cl_user ||
15484                 error "User '$cl_user' not found in changelog_users"
15485 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15486         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15487         rmdir $DIR/$tdir/1/1 & sleep 1
15488         mkdir $DIR/$tdir/2
15489         touch $DIR/$tdir/2/2
15490         rm -rf $DIR/$tdir/2
15491
15492         wait
15493         sleep 4
15494
15495         changelog_dump | grep rmdir || error "rmdir not recorded"
15496 }
15497 run_test 160k "Verify that changelog records are not lost"
15498
15499 # Verifies that a file passed as a parameter has recently had an operation
15500 # performed on it that has generated an MTIME changelog which contains the
15501 # correct parent FID. As files might reside on a different MDT from the
15502 # parent directory in DNE configurations, the FIDs are translated to paths
15503 # before being compared, which should be identical
15504 compare_mtime_changelog() {
15505         local file="${1}"
15506         local mdtidx
15507         local mtime
15508         local cl_fid
15509         local pdir
15510         local dir
15511
15512         mdtidx=$($LFS getstripe --mdt-index $file)
15513         mdtidx=$(printf "%04x" $mdtidx)
15514
15515         # Obtain the parent FID from the MTIME changelog
15516         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15517         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15518
15519         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15520         [ -z "$cl_fid" ] && error "parent FID not present"
15521
15522         # Verify that the path for the parent FID is the same as the path for
15523         # the test directory
15524         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15525
15526         dir=$(dirname $1)
15527
15528         [[ "${pdir%/}" == "$dir" ]] ||
15529                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15530 }
15531
15532 test_160l() {
15533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15534
15535         remote_mds_nodsh && skip "remote MDS with nodsh"
15536         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15537                 skip "Need MDS version at least 2.13.55"
15538
15539         local cl_user
15540
15541         changelog_register || error "changelog_register failed"
15542         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15543
15544         changelog_users $SINGLEMDS | grep -q $cl_user ||
15545                 error "User '$cl_user' not found in changelog_users"
15546
15547         # Clear some types so that MTIME changelogs are generated
15548         changelog_chmask "-CREAT"
15549         changelog_chmask "-CLOSE"
15550
15551         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15552
15553         # Test CL_MTIME during setattr
15554         touch $DIR/$tdir/$tfile
15555         compare_mtime_changelog $DIR/$tdir/$tfile
15556
15557         # Test CL_MTIME during close
15558         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15559         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15560 }
15561 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15562
15563 test_161a() {
15564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15565
15566         test_mkdir -c1 $DIR/$tdir
15567         cp /etc/hosts $DIR/$tdir/$tfile
15568         test_mkdir -c1 $DIR/$tdir/foo1
15569         test_mkdir -c1 $DIR/$tdir/foo2
15570         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15571         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15572         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15573         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15574         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15575         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15576                 $LFS fid2path $DIR $FID
15577                 error "bad link ea"
15578         fi
15579         # middle
15580         rm $DIR/$tdir/foo2/zachary
15581         # last
15582         rm $DIR/$tdir/foo2/thor
15583         # first
15584         rm $DIR/$tdir/$tfile
15585         # rename
15586         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15587         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15588                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15589         rm $DIR/$tdir/foo2/maggie
15590
15591         # overflow the EA
15592         local longname=$tfile.avg_len_is_thirty_two_
15593         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15594                 error_noexit 'failed to unlink many hardlinks'" EXIT
15595         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15596                 error "failed to hardlink many files"
15597         links=$($LFS fid2path $DIR $FID | wc -l)
15598         echo -n "${links}/1000 links in link EA"
15599         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15600 }
15601 run_test 161a "link ea sanity"
15602
15603 test_161b() {
15604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15605         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15606
15607         local MDTIDX=1
15608         local remote_dir=$DIR/$tdir/remote_dir
15609
15610         mkdir -p $DIR/$tdir
15611         $LFS mkdir -i $MDTIDX $remote_dir ||
15612                 error "create remote directory failed"
15613
15614         cp /etc/hosts $remote_dir/$tfile
15615         mkdir -p $remote_dir/foo1
15616         mkdir -p $remote_dir/foo2
15617         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15618         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15619         ln $remote_dir/$tfile $remote_dir/foo1/luna
15620         ln $remote_dir/$tfile $remote_dir/foo2/thor
15621
15622         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15623                      tr -d ']')
15624         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15625                 $LFS fid2path $DIR $FID
15626                 error "bad link ea"
15627         fi
15628         # middle
15629         rm $remote_dir/foo2/zachary
15630         # last
15631         rm $remote_dir/foo2/thor
15632         # first
15633         rm $remote_dir/$tfile
15634         # rename
15635         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15636         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15637         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15638                 $LFS fid2path $DIR $FID
15639                 error "bad link rename"
15640         fi
15641         rm $remote_dir/foo2/maggie
15642
15643         # overflow the EA
15644         local longname=filename_avg_len_is_thirty_two_
15645         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15646                 error "failed to hardlink many files"
15647         links=$($LFS fid2path $DIR $FID | wc -l)
15648         echo -n "${links}/1000 links in link EA"
15649         [[ ${links} -gt 60 ]] ||
15650                 error "expected at least 60 links in link EA"
15651         unlinkmany $remote_dir/foo2/$longname 1000 ||
15652         error "failed to unlink many hardlinks"
15653 }
15654 run_test 161b "link ea sanity under remote directory"
15655
15656 test_161c() {
15657         remote_mds_nodsh && skip "remote MDS with nodsh"
15658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15659         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15660                 skip "Need MDS version at least 2.1.5"
15661
15662         # define CLF_RENAME_LAST 0x0001
15663         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15664         changelog_register || error "changelog_register failed"
15665
15666         rm -rf $DIR/$tdir
15667         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15668         touch $DIR/$tdir/foo_161c
15669         touch $DIR/$tdir/bar_161c
15670         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15671         changelog_dump | grep RENME | tail -n 5
15672         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15673         changelog_clear 0 || error "changelog_clear failed"
15674         if [ x$flags != "x0x1" ]; then
15675                 error "flag $flags is not 0x1"
15676         fi
15677
15678         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15679         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15680         touch $DIR/$tdir/foo_161c
15681         touch $DIR/$tdir/bar_161c
15682         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15683         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15684         changelog_dump | grep RENME | tail -n 5
15685         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15686         changelog_clear 0 || error "changelog_clear failed"
15687         if [ x$flags != "x0x0" ]; then
15688                 error "flag $flags is not 0x0"
15689         fi
15690         echo "rename overwrite a target having nlink > 1," \
15691                 "changelog record has flags of $flags"
15692
15693         # rename doesn't overwrite a target (changelog flag 0x0)
15694         touch $DIR/$tdir/foo_161c
15695         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15696         changelog_dump | grep RENME | tail -n 5
15697         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15698         changelog_clear 0 || error "changelog_clear failed"
15699         if [ x$flags != "x0x0" ]; then
15700                 error "flag $flags is not 0x0"
15701         fi
15702         echo "rename doesn't overwrite a target," \
15703                 "changelog record has flags of $flags"
15704
15705         # define CLF_UNLINK_LAST 0x0001
15706         # unlink a file having nlink = 1 (changelog flag 0x1)
15707         rm -f $DIR/$tdir/foo2_161c
15708         changelog_dump | grep UNLNK | tail -n 5
15709         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15710         changelog_clear 0 || error "changelog_clear failed"
15711         if [ x$flags != "x0x1" ]; then
15712                 error "flag $flags is not 0x1"
15713         fi
15714         echo "unlink a file having nlink = 1," \
15715                 "changelog record has flags of $flags"
15716
15717         # unlink a file having nlink > 1 (changelog flag 0x0)
15718         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15719         rm -f $DIR/$tdir/foobar_161c
15720         changelog_dump | grep UNLNK | tail -n 5
15721         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15722         changelog_clear 0 || error "changelog_clear failed"
15723         if [ x$flags != "x0x0" ]; then
15724                 error "flag $flags is not 0x0"
15725         fi
15726         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15727 }
15728 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15729
15730 test_161d() {
15731         remote_mds_nodsh && skip "remote MDS with nodsh"
15732         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15733
15734         local pid
15735         local fid
15736
15737         changelog_register || error "changelog_register failed"
15738
15739         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15740         # interfer with $MOUNT/.lustre/fid/ access
15741         mkdir $DIR/$tdir
15742         [[ $? -eq 0 ]] || error "mkdir failed"
15743
15744         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15745         $LCTL set_param fail_loc=0x8000140c
15746         # 5s pause
15747         $LCTL set_param fail_val=5
15748
15749         # create file
15750         echo foofoo > $DIR/$tdir/$tfile &
15751         pid=$!
15752
15753         # wait for create to be delayed
15754         sleep 2
15755
15756         ps -p $pid
15757         [[ $? -eq 0 ]] || error "create should be blocked"
15758
15759         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15760         stack_trap "rm -f $tempfile"
15761         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15762         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15763         # some delay may occur during ChangeLog publishing and file read just
15764         # above, that could allow file write to happen finally
15765         [[ -s $tempfile ]] && echo "file should be empty"
15766
15767         $LCTL set_param fail_loc=0
15768
15769         wait $pid
15770         [[ $? -eq 0 ]] || error "create failed"
15771 }
15772 run_test 161d "create with concurrent .lustre/fid access"
15773
15774 check_path() {
15775         local expected="$1"
15776         shift
15777         local fid="$2"
15778
15779         local path
15780         path=$($LFS fid2path "$@")
15781         local rc=$?
15782
15783         if [ $rc -ne 0 ]; then
15784                 error "path looked up of '$expected' failed: rc=$rc"
15785         elif [ "$path" != "$expected" ]; then
15786                 error "path looked up '$path' instead of '$expected'"
15787         else
15788                 echo "FID '$fid' resolves to path '$path' as expected"
15789         fi
15790 }
15791
15792 test_162a() { # was test_162
15793         test_mkdir -p -c1 $DIR/$tdir/d2
15794         touch $DIR/$tdir/d2/$tfile
15795         touch $DIR/$tdir/d2/x1
15796         touch $DIR/$tdir/d2/x2
15797         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15798         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15799         # regular file
15800         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15801         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15802
15803         # softlink
15804         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15805         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15806         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15807
15808         # softlink to wrong file
15809         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15810         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15811         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15812
15813         # hardlink
15814         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15815         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15816         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15817         # fid2path dir/fsname should both work
15818         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15819         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15820
15821         # hardlink count: check that there are 2 links
15822         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15823         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15824
15825         # hardlink indexing: remove the first link
15826         rm $DIR/$tdir/d2/p/q/r/hlink
15827         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15828 }
15829 run_test 162a "path lookup sanity"
15830
15831 test_162b() {
15832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15834
15835         mkdir $DIR/$tdir
15836         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15837                                 error "create striped dir failed"
15838
15839         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15840                                         tail -n 1 | awk '{print $2}')
15841         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15842
15843         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15844         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15845
15846         # regular file
15847         for ((i=0;i<5;i++)); do
15848                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15849                         error "get fid for f$i failed"
15850                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15851
15852                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15853                         error "get fid for d$i failed"
15854                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15855         done
15856
15857         return 0
15858 }
15859 run_test 162b "striped directory path lookup sanity"
15860
15861 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15862 test_162c() {
15863         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15864                 skip "Need MDS version at least 2.7.51"
15865
15866         local lpath=$tdir.local
15867         local rpath=$tdir.remote
15868
15869         test_mkdir $DIR/$lpath
15870         test_mkdir $DIR/$rpath
15871
15872         for ((i = 0; i <= 101; i++)); do
15873                 lpath="$lpath/$i"
15874                 mkdir $DIR/$lpath
15875                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15876                         error "get fid for local directory $DIR/$lpath failed"
15877                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15878
15879                 rpath="$rpath/$i"
15880                 test_mkdir $DIR/$rpath
15881                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15882                         error "get fid for remote directory $DIR/$rpath failed"
15883                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15884         done
15885
15886         return 0
15887 }
15888 run_test 162c "fid2path works with paths 100 or more directories deep"
15889
15890 oalr_event_count() {
15891         local event="${1}"
15892         local trace="${2}"
15893
15894         awk -v name="${FSNAME}-OST0000" \
15895             -v event="${event}" \
15896             '$1 == "TRACE" && $2 == event && $3 == name' \
15897             "${trace}" |
15898         wc -l
15899 }
15900
15901 oalr_expect_event_count() {
15902         local event="${1}"
15903         local trace="${2}"
15904         local expect="${3}"
15905         local count
15906
15907         count=$(oalr_event_count "${event}" "${trace}")
15908         if ((count == expect)); then
15909                 return 0
15910         fi
15911
15912         error_noexit "${event} event count was '${count}', expected ${expect}"
15913         cat "${trace}" >&2
15914         exit 1
15915 }
15916
15917 cleanup_165() {
15918         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15919         stop ost1
15920         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15921 }
15922
15923 setup_165() {
15924         sync # Flush previous IOs so we can count log entries.
15925         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15926         stack_trap cleanup_165 EXIT
15927 }
15928
15929 test_165a() {
15930         local trace="/tmp/${tfile}.trace"
15931         local rc
15932         local count
15933
15934         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15935                 skip "OFD access log unsupported"
15936
15937         setup_165
15938         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15939         sleep 5
15940
15941         do_facet ost1 ofd_access_log_reader --list
15942         stop ost1
15943
15944         do_facet ost1 killall -TERM ofd_access_log_reader
15945         wait
15946         rc=$?
15947
15948         if ((rc != 0)); then
15949                 error "ofd_access_log_reader exited with rc = '${rc}'"
15950         fi
15951
15952         # Parse trace file for discovery events:
15953         oalr_expect_event_count alr_log_add "${trace}" 1
15954         oalr_expect_event_count alr_log_eof "${trace}" 1
15955         oalr_expect_event_count alr_log_free "${trace}" 1
15956 }
15957 run_test 165a "ofd access log discovery"
15958
15959 test_165b() {
15960         local trace="/tmp/${tfile}.trace"
15961         local file="${DIR}/${tfile}"
15962         local pfid1
15963         local pfid2
15964         local -a entry
15965         local rc
15966         local count
15967         local size
15968         local flags
15969
15970         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15971                 skip "OFD access log unsupported"
15972
15973         setup_165
15974         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15975         sleep 5
15976
15977         do_facet ost1 ofd_access_log_reader --list
15978
15979         lfs setstripe -c 1 -i 0 "${file}"
15980         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15981                 error "cannot create '${file}'"
15982
15983         sleep 5
15984         do_facet ost1 killall -TERM ofd_access_log_reader
15985         wait
15986         rc=$?
15987
15988         if ((rc != 0)); then
15989                 error "ofd_access_log_reader exited with rc = '${rc}'"
15990         fi
15991
15992         oalr_expect_event_count alr_log_entry "${trace}" 1
15993
15994         pfid1=$($LFS path2fid "${file}")
15995
15996         # 1     2             3   4    5     6   7    8    9     10
15997         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15998         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15999
16000         echo "entry = '${entry[*]}'" >&2
16001
16002         pfid2=${entry[4]}
16003         if [[ "${pfid1}" != "${pfid2}" ]]; then
16004                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16005         fi
16006
16007         size=${entry[8]}
16008         if ((size != 1048576)); then
16009                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16010         fi
16011
16012         flags=${entry[10]}
16013         if [[ "${flags}" != "w" ]]; then
16014                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16015         fi
16016
16017         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16018         sleep 5
16019
16020         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16021                 error "cannot read '${file}'"
16022         sleep 5
16023
16024         do_facet ost1 killall -TERM ofd_access_log_reader
16025         wait
16026         rc=$?
16027
16028         if ((rc != 0)); then
16029                 error "ofd_access_log_reader exited with rc = '${rc}'"
16030         fi
16031
16032         oalr_expect_event_count alr_log_entry "${trace}" 1
16033
16034         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16035         echo "entry = '${entry[*]}'" >&2
16036
16037         pfid2=${entry[4]}
16038         if [[ "${pfid1}" != "${pfid2}" ]]; then
16039                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16040         fi
16041
16042         size=${entry[8]}
16043         if ((size != 524288)); then
16044                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16045         fi
16046
16047         flags=${entry[10]}
16048         if [[ "${flags}" != "r" ]]; then
16049                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16050         fi
16051 }
16052 run_test 165b "ofd access log entries are produced and consumed"
16053
16054 test_165c() {
16055         local trace="/tmp/${tfile}.trace"
16056         local file="${DIR}/${tdir}/${tfile}"
16057
16058         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16059                 skip "OFD access log unsupported"
16060
16061         test_mkdir "${DIR}/${tdir}"
16062
16063         setup_165
16064         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16065         sleep 5
16066
16067         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16068
16069         # 4096 / 64 = 64. Create twice as many entries.
16070         for ((i = 0; i < 128; i++)); do
16071                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16072                         error "cannot create file"
16073         done
16074
16075         sync
16076
16077         do_facet ost1 killall -TERM ofd_access_log_reader
16078         wait
16079         rc=$?
16080         if ((rc != 0)); then
16081                 error "ofd_access_log_reader exited with rc = '${rc}'"
16082         fi
16083
16084         unlinkmany  "${file}-%d" 128
16085 }
16086 run_test 165c "full ofd access logs do not block IOs"
16087
16088 oal_get_read_count() {
16089         local stats="$1"
16090
16091         # STATS lustre-OST0001 alr_read_count 1
16092
16093         do_facet ost1 cat "${stats}" |
16094         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16095              END { print count; }'
16096 }
16097
16098 oal_expect_read_count() {
16099         local stats="$1"
16100         local count
16101         local expect="$2"
16102
16103         # Ask ofd_access_log_reader to write stats.
16104         do_facet ost1 killall -USR1 ofd_access_log_reader
16105
16106         # Allow some time for things to happen.
16107         sleep 1
16108
16109         count=$(oal_get_read_count "${stats}")
16110         if ((count == expect)); then
16111                 return 0
16112         fi
16113
16114         error_noexit "bad read count, got ${count}, expected ${expect}"
16115         do_facet ost1 cat "${stats}" >&2
16116         exit 1
16117 }
16118
16119 test_165d() {
16120         local stats="/tmp/${tfile}.stats"
16121         local file="${DIR}/${tdir}/${tfile}"
16122         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16123
16124         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16125                 skip "OFD access log unsupported"
16126
16127         test_mkdir "${DIR}/${tdir}"
16128
16129         setup_165
16130         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16131         sleep 5
16132
16133         lfs setstripe -c 1 -i 0 "${file}"
16134
16135         do_facet ost1 lctl set_param "${param}=rw"
16136         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16137                 error "cannot create '${file}'"
16138         oal_expect_read_count "${stats}" 1
16139
16140         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16141                 error "cannot read '${file}'"
16142         oal_expect_read_count "${stats}" 2
16143
16144         do_facet ost1 lctl set_param "${param}=r"
16145         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16146                 error "cannot create '${file}'"
16147         oal_expect_read_count "${stats}" 2
16148
16149         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16150                 error "cannot read '${file}'"
16151         oal_expect_read_count "${stats}" 3
16152
16153         do_facet ost1 lctl set_param "${param}=w"
16154         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16155                 error "cannot create '${file}'"
16156         oal_expect_read_count "${stats}" 4
16157
16158         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16159                 error "cannot read '${file}'"
16160         oal_expect_read_count "${stats}" 4
16161
16162         do_facet ost1 lctl set_param "${param}=0"
16163         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16164                 error "cannot create '${file}'"
16165         oal_expect_read_count "${stats}" 4
16166
16167         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16168                 error "cannot read '${file}'"
16169         oal_expect_read_count "${stats}" 4
16170
16171         do_facet ost1 killall -TERM ofd_access_log_reader
16172         wait
16173         rc=$?
16174         if ((rc != 0)); then
16175                 error "ofd_access_log_reader exited with rc = '${rc}'"
16176         fi
16177 }
16178 run_test 165d "ofd_access_log mask works"
16179
16180 test_165e() {
16181         local stats="/tmp/${tfile}.stats"
16182         local file0="${DIR}/${tdir}-0/${tfile}"
16183         local file1="${DIR}/${tdir}-1/${tfile}"
16184
16185         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16186                 skip "OFD access log unsupported"
16187
16188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16189
16190         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16191         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16192
16193         lfs setstripe -c 1 -i 0 "${file0}"
16194         lfs setstripe -c 1 -i 0 "${file1}"
16195
16196         setup_165
16197         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16198         sleep 5
16199
16200         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16201                 error "cannot create '${file0}'"
16202         sync
16203         oal_expect_read_count "${stats}" 0
16204
16205         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16206                 error "cannot create '${file1}'"
16207         sync
16208         oal_expect_read_count "${stats}" 1
16209
16210         do_facet ost1 killall -TERM ofd_access_log_reader
16211         wait
16212         rc=$?
16213         if ((rc != 0)); then
16214                 error "ofd_access_log_reader exited with rc = '${rc}'"
16215         fi
16216 }
16217 run_test 165e "ofd_access_log MDT index filter works"
16218
16219 test_165f() {
16220         local trace="/tmp/${tfile}.trace"
16221         local rc
16222         local count
16223
16224         setup_165
16225         do_facet ost1 timeout 60 ofd_access_log_reader \
16226                 --exit-on-close --debug=- --trace=- > "${trace}" &
16227         sleep 5
16228         stop ost1
16229
16230         wait
16231         rc=$?
16232
16233         if ((rc != 0)); then
16234                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16235                 cat "${trace}"
16236                 exit 1
16237         fi
16238 }
16239 run_test 165f "ofd_access_log_reader --exit-on-close works"
16240
16241 test_169() {
16242         # do directio so as not to populate the page cache
16243         log "creating a 10 Mb file"
16244         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16245                 error "multiop failed while creating a file"
16246         log "starting reads"
16247         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16248         log "truncating the file"
16249         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16250                 error "multiop failed while truncating the file"
16251         log "killing dd"
16252         kill %+ || true # reads might have finished
16253         echo "wait until dd is finished"
16254         wait
16255         log "removing the temporary file"
16256         rm -rf $DIR/$tfile || error "tmp file removal failed"
16257 }
16258 run_test 169 "parallel read and truncate should not deadlock"
16259
16260 test_170() {
16261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16262
16263         $LCTL clear     # bug 18514
16264         $LCTL debug_daemon start $TMP/${tfile}_log_good
16265         touch $DIR/$tfile
16266         $LCTL debug_daemon stop
16267         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16268                 error "sed failed to read log_good"
16269
16270         $LCTL debug_daemon start $TMP/${tfile}_log_good
16271         rm -rf $DIR/$tfile
16272         $LCTL debug_daemon stop
16273
16274         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16275                error "lctl df log_bad failed"
16276
16277         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16278         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16279
16280         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16281         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16282
16283         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16284                 error "bad_line good_line1 good_line2 are empty"
16285
16286         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16287         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16288         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16289
16290         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16291         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16292         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16293
16294         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16295                 error "bad_line_new good_line_new are empty"
16296
16297         local expected_good=$((good_line1 + good_line2*2))
16298
16299         rm -f $TMP/${tfile}*
16300         # LU-231, short malformed line may not be counted into bad lines
16301         if [ $bad_line -ne $bad_line_new ] &&
16302                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16303                 error "expected $bad_line bad lines, but got $bad_line_new"
16304                 return 1
16305         fi
16306
16307         if [ $expected_good -ne $good_line_new ]; then
16308                 error "expected $expected_good good lines, but got $good_line_new"
16309                 return 2
16310         fi
16311         true
16312 }
16313 run_test 170 "test lctl df to handle corrupted log ====================="
16314
16315 test_171() { # bug20592
16316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16317
16318         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16319         $LCTL set_param fail_loc=0x50e
16320         $LCTL set_param fail_val=3000
16321         multiop_bg_pause $DIR/$tfile O_s || true
16322         local MULTIPID=$!
16323         kill -USR1 $MULTIPID
16324         # cause log dump
16325         sleep 3
16326         wait $MULTIPID
16327         if dmesg | grep "recursive fault"; then
16328                 error "caught a recursive fault"
16329         fi
16330         $LCTL set_param fail_loc=0
16331         true
16332 }
16333 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16334
16335 # it would be good to share it with obdfilter-survey/iokit-libecho code
16336 setup_obdecho_osc () {
16337         local rc=0
16338         local ost_nid=$1
16339         local obdfilter_name=$2
16340         echo "Creating new osc for $obdfilter_name on $ost_nid"
16341         # make sure we can find loopback nid
16342         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16343
16344         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16345                            ${obdfilter_name}_osc_UUID || rc=2; }
16346         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16347                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16348         return $rc
16349 }
16350
16351 cleanup_obdecho_osc () {
16352         local obdfilter_name=$1
16353         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16354         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16355         return 0
16356 }
16357
16358 obdecho_test() {
16359         local OBD=$1
16360         local node=$2
16361         local pages=${3:-64}
16362         local rc=0
16363         local id
16364
16365         local count=10
16366         local obd_size=$(get_obd_size $node $OBD)
16367         local page_size=$(get_page_size $node)
16368         if [[ -n "$obd_size" ]]; then
16369                 local new_count=$((obd_size / (pages * page_size / 1024)))
16370                 [[ $new_count -ge $count ]] || count=$new_count
16371         fi
16372
16373         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16374         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16375                            rc=2; }
16376         if [ $rc -eq 0 ]; then
16377             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16378             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16379         fi
16380         echo "New object id is $id"
16381         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16382                            rc=4; }
16383         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16384                            "test_brw $count w v $pages $id" || rc=4; }
16385         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16386                            rc=4; }
16387         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16388                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16389         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16390                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16391         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16392         return $rc
16393 }
16394
16395 test_180a() {
16396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16397
16398         if ! [ -d /sys/fs/lustre/echo_client ] &&
16399            ! module_loaded obdecho; then
16400                 load_module obdecho/obdecho &&
16401                         stack_trap "rmmod obdecho" EXIT ||
16402                         error "unable to load obdecho on client"
16403         fi
16404
16405         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16406         local host=$($LCTL get_param -n osc.$osc.import |
16407                      awk '/current_connection:/ { print $2 }' )
16408         local target=$($LCTL get_param -n osc.$osc.import |
16409                        awk '/target:/ { print $2 }' )
16410         target=${target%_UUID}
16411
16412         if [ -n "$target" ]; then
16413                 setup_obdecho_osc $host $target &&
16414                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16415                         { error "obdecho setup failed with $?"; return; }
16416
16417                 obdecho_test ${target}_osc client ||
16418                         error "obdecho_test failed on ${target}_osc"
16419         else
16420                 $LCTL get_param osc.$osc.import
16421                 error "there is no osc.$osc.import target"
16422         fi
16423 }
16424 run_test 180a "test obdecho on osc"
16425
16426 test_180b() {
16427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16428         remote_ost_nodsh && skip "remote OST with nodsh"
16429
16430         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16431                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16432                 error "failed to load module obdecho"
16433
16434         local target=$(do_facet ost1 $LCTL dl |
16435                        awk '/obdfilter/ { print $4; exit; }')
16436
16437         if [ -n "$target" ]; then
16438                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16439         else
16440                 do_facet ost1 $LCTL dl
16441                 error "there is no obdfilter target on ost1"
16442         fi
16443 }
16444 run_test 180b "test obdecho directly on obdfilter"
16445
16446 test_180c() { # LU-2598
16447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16448         remote_ost_nodsh && skip "remote OST with nodsh"
16449         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16450                 skip "Need MDS version at least 2.4.0"
16451
16452         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16453                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16454                 error "failed to load module obdecho"
16455
16456         local target=$(do_facet ost1 $LCTL dl |
16457                        awk '/obdfilter/ { print $4; exit; }')
16458
16459         if [ -n "$target" ]; then
16460                 local pages=16384 # 64MB bulk I/O RPC size
16461
16462                 obdecho_test "$target" ost1 "$pages" ||
16463                         error "obdecho_test with pages=$pages failed with $?"
16464         else
16465                 do_facet ost1 $LCTL dl
16466                 error "there is no obdfilter target on ost1"
16467         fi
16468 }
16469 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16470
16471 test_181() { # bug 22177
16472         test_mkdir $DIR/$tdir
16473         # create enough files to index the directory
16474         createmany -o $DIR/$tdir/foobar 4000
16475         # print attributes for debug purpose
16476         lsattr -d .
16477         # open dir
16478         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16479         MULTIPID=$!
16480         # remove the files & current working dir
16481         unlinkmany $DIR/$tdir/foobar 4000
16482         rmdir $DIR/$tdir
16483         kill -USR1 $MULTIPID
16484         wait $MULTIPID
16485         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16486         return 0
16487 }
16488 run_test 181 "Test open-unlinked dir ========================"
16489
16490 test_182() {
16491         local fcount=1000
16492         local tcount=10
16493
16494         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16495
16496         $LCTL set_param mdc.*.rpc_stats=clear
16497
16498         for (( i = 0; i < $tcount; i++ )) ; do
16499                 mkdir $DIR/$tdir/$i
16500         done
16501
16502         for (( i = 0; i < $tcount; i++ )) ; do
16503                 createmany -o $DIR/$tdir/$i/f- $fcount &
16504         done
16505         wait
16506
16507         for (( i = 0; i < $tcount; i++ )) ; do
16508                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16509         done
16510         wait
16511
16512         $LCTL get_param mdc.*.rpc_stats
16513
16514         rm -rf $DIR/$tdir
16515 }
16516 run_test 182 "Test parallel modify metadata operations ================"
16517
16518 test_183() { # LU-2275
16519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16520         remote_mds_nodsh && skip "remote MDS with nodsh"
16521         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16522                 skip "Need MDS version at least 2.3.56"
16523
16524         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16525         echo aaa > $DIR/$tdir/$tfile
16526
16527 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16528         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16529
16530         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16531         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16532
16533         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16534
16535         # Flush negative dentry cache
16536         touch $DIR/$tdir/$tfile
16537
16538         # We are not checking for any leaked references here, they'll
16539         # become evident next time we do cleanup with module unload.
16540         rm -rf $DIR/$tdir
16541 }
16542 run_test 183 "No crash or request leak in case of strange dispositions ========"
16543
16544 # test suite 184 is for LU-2016, LU-2017
16545 test_184a() {
16546         check_swap_layouts_support
16547
16548         dir0=$DIR/$tdir/$testnum
16549         test_mkdir -p -c1 $dir0
16550         ref1=/etc/passwd
16551         ref2=/etc/group
16552         file1=$dir0/f1
16553         file2=$dir0/f2
16554         $LFS setstripe -c1 $file1
16555         cp $ref1 $file1
16556         $LFS setstripe -c2 $file2
16557         cp $ref2 $file2
16558         gen1=$($LFS getstripe -g $file1)
16559         gen2=$($LFS getstripe -g $file2)
16560
16561         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16562         gen=$($LFS getstripe -g $file1)
16563         [[ $gen1 != $gen ]] ||
16564                 "Layout generation on $file1 does not change"
16565         gen=$($LFS getstripe -g $file2)
16566         [[ $gen2 != $gen ]] ||
16567                 "Layout generation on $file2 does not change"
16568
16569         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16570         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16571
16572         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16573 }
16574 run_test 184a "Basic layout swap"
16575
16576 test_184b() {
16577         check_swap_layouts_support
16578
16579         dir0=$DIR/$tdir/$testnum
16580         mkdir -p $dir0 || error "creating dir $dir0"
16581         file1=$dir0/f1
16582         file2=$dir0/f2
16583         file3=$dir0/f3
16584         dir1=$dir0/d1
16585         dir2=$dir0/d2
16586         mkdir $dir1 $dir2
16587         $LFS setstripe -c1 $file1
16588         $LFS setstripe -c2 $file2
16589         $LFS setstripe -c1 $file3
16590         chown $RUNAS_ID $file3
16591         gen1=$($LFS getstripe -g $file1)
16592         gen2=$($LFS getstripe -g $file2)
16593
16594         $LFS swap_layouts $dir1 $dir2 &&
16595                 error "swap of directories layouts should fail"
16596         $LFS swap_layouts $dir1 $file1 &&
16597                 error "swap of directory and file layouts should fail"
16598         $RUNAS $LFS swap_layouts $file1 $file2 &&
16599                 error "swap of file we cannot write should fail"
16600         $LFS swap_layouts $file1 $file3 &&
16601                 error "swap of file with different owner should fail"
16602         /bin/true # to clear error code
16603 }
16604 run_test 184b "Forbidden layout swap (will generate errors)"
16605
16606 test_184c() {
16607         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16608         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16609         check_swap_layouts_support
16610         check_swap_layout_no_dom $DIR
16611
16612         local dir0=$DIR/$tdir/$testnum
16613         mkdir -p $dir0 || error "creating dir $dir0"
16614
16615         local ref1=$dir0/ref1
16616         local ref2=$dir0/ref2
16617         local file1=$dir0/file1
16618         local file2=$dir0/file2
16619         # create a file large enough for the concurrent test
16620         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16621         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16622         echo "ref file size: ref1($(stat -c %s $ref1))," \
16623              "ref2($(stat -c %s $ref2))"
16624
16625         cp $ref2 $file2
16626         dd if=$ref1 of=$file1 bs=16k &
16627         local DD_PID=$!
16628
16629         # Make sure dd starts to copy file, but wait at most 5 seconds
16630         local loops=0
16631         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16632
16633         $LFS swap_layouts $file1 $file2
16634         local rc=$?
16635         wait $DD_PID
16636         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16637         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16638
16639         # how many bytes copied before swapping layout
16640         local copied=$(stat -c %s $file2)
16641         local remaining=$(stat -c %s $ref1)
16642         remaining=$((remaining - copied))
16643         echo "Copied $copied bytes before swapping layout..."
16644
16645         cmp -n $copied $file1 $ref2 | grep differ &&
16646                 error "Content mismatch [0, $copied) of ref2 and file1"
16647         cmp -n $copied $file2 $ref1 ||
16648                 error "Content mismatch [0, $copied) of ref1 and file2"
16649         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16650                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16651
16652         # clean up
16653         rm -f $ref1 $ref2 $file1 $file2
16654 }
16655 run_test 184c "Concurrent write and layout swap"
16656
16657 test_184d() {
16658         check_swap_layouts_support
16659         check_swap_layout_no_dom $DIR
16660         [ -z "$(which getfattr 2>/dev/null)" ] &&
16661                 skip_env "no getfattr command"
16662
16663         local file1=$DIR/$tdir/$tfile-1
16664         local file2=$DIR/$tdir/$tfile-2
16665         local file3=$DIR/$tdir/$tfile-3
16666         local lovea1
16667         local lovea2
16668
16669         mkdir -p $DIR/$tdir
16670         touch $file1 || error "create $file1 failed"
16671         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16672                 error "create $file2 failed"
16673         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16674                 error "create $file3 failed"
16675         lovea1=$(get_layout_param $file1)
16676
16677         $LFS swap_layouts $file2 $file3 ||
16678                 error "swap $file2 $file3 layouts failed"
16679         $LFS swap_layouts $file1 $file2 ||
16680                 error "swap $file1 $file2 layouts failed"
16681
16682         lovea2=$(get_layout_param $file2)
16683         echo "$lovea1"
16684         echo "$lovea2"
16685         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16686
16687         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16688         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16689 }
16690 run_test 184d "allow stripeless layouts swap"
16691
16692 test_184e() {
16693         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16694                 skip "Need MDS version at least 2.6.94"
16695         check_swap_layouts_support
16696         check_swap_layout_no_dom $DIR
16697         [ -z "$(which getfattr 2>/dev/null)" ] &&
16698                 skip_env "no getfattr command"
16699
16700         local file1=$DIR/$tdir/$tfile-1
16701         local file2=$DIR/$tdir/$tfile-2
16702         local file3=$DIR/$tdir/$tfile-3
16703         local lovea
16704
16705         mkdir -p $DIR/$tdir
16706         touch $file1 || error "create $file1 failed"
16707         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16708                 error "create $file2 failed"
16709         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16710                 error "create $file3 failed"
16711
16712         $LFS swap_layouts $file1 $file2 ||
16713                 error "swap $file1 $file2 layouts failed"
16714
16715         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16716         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16717
16718         echo 123 > $file1 || error "Should be able to write into $file1"
16719
16720         $LFS swap_layouts $file1 $file3 ||
16721                 error "swap $file1 $file3 layouts failed"
16722
16723         echo 123 > $file1 || error "Should be able to write into $file1"
16724
16725         rm -rf $file1 $file2 $file3
16726 }
16727 run_test 184e "Recreate layout after stripeless layout swaps"
16728
16729 test_184f() {
16730         # Create a file with name longer than sizeof(struct stat) ==
16731         # 144 to see if we can get chars from the file name to appear
16732         # in the returned striping. Note that 'f' == 0x66.
16733         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16734
16735         mkdir -p $DIR/$tdir
16736         mcreate $DIR/$tdir/$file
16737         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16738                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16739         fi
16740 }
16741 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16742
16743 test_185() { # LU-2441
16744         # LU-3553 - no volatile file support in old servers
16745         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16746                 skip "Need MDS version at least 2.3.60"
16747
16748         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16749         touch $DIR/$tdir/spoo
16750         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16751         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16752                 error "cannot create/write a volatile file"
16753         [ "$FILESET" == "" ] &&
16754         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16755                 error "FID is still valid after close"
16756
16757         multiop_bg_pause $DIR/$tdir vVw4096_c
16758         local multi_pid=$!
16759
16760         local OLD_IFS=$IFS
16761         IFS=":"
16762         local fidv=($fid)
16763         IFS=$OLD_IFS
16764         # assume that the next FID for this client is sequential, since stdout
16765         # is unfortunately eaten by multiop_bg_pause
16766         local n=$((${fidv[1]} + 1))
16767         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16768         if [ "$FILESET" == "" ]; then
16769                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16770                         error "FID is missing before close"
16771         fi
16772         kill -USR1 $multi_pid
16773         # 1 second delay, so if mtime change we will see it
16774         sleep 1
16775         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16776         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16777 }
16778 run_test 185 "Volatile file support"
16779
16780 function create_check_volatile() {
16781         local idx=$1
16782         local tgt
16783
16784         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16785         local PID=$!
16786         sleep 1
16787         local FID=$(cat /tmp/${tfile}.fid)
16788         [ "$FID" == "" ] && error "can't get FID for volatile"
16789         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16790         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16791         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16792         kill -USR1 $PID
16793         wait
16794         sleep 1
16795         cancel_lru_locks mdc # flush opencache
16796         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16797         return 0
16798 }
16799
16800 test_185a(){
16801         # LU-12516 - volatile creation via .lustre
16802         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16803                 skip "Need MDS version at least 2.3.55"
16804
16805         create_check_volatile 0
16806         [ $MDSCOUNT -lt 2 ] && return 0
16807
16808         # DNE case
16809         create_check_volatile 1
16810
16811         return 0
16812 }
16813 run_test 185a "Volatile file creation in .lustre/fid/"
16814
16815 test_187a() {
16816         remote_mds_nodsh && skip "remote MDS with nodsh"
16817         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16818                 skip "Need MDS version at least 2.3.0"
16819
16820         local dir0=$DIR/$tdir/$testnum
16821         mkdir -p $dir0 || error "creating dir $dir0"
16822
16823         local file=$dir0/file1
16824         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16825         local dv1=$($LFS data_version $file)
16826         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16827         local dv2=$($LFS data_version $file)
16828         [[ $dv1 != $dv2 ]] ||
16829                 error "data version did not change on write $dv1 == $dv2"
16830
16831         # clean up
16832         rm -f $file1
16833 }
16834 run_test 187a "Test data version change"
16835
16836 test_187b() {
16837         remote_mds_nodsh && skip "remote MDS with nodsh"
16838         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16839                 skip "Need MDS version at least 2.3.0"
16840
16841         local dir0=$DIR/$tdir/$testnum
16842         mkdir -p $dir0 || error "creating dir $dir0"
16843
16844         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16845         [[ ${DV[0]} != ${DV[1]} ]] ||
16846                 error "data version did not change on write"\
16847                       " ${DV[0]} == ${DV[1]}"
16848
16849         # clean up
16850         rm -f $file1
16851 }
16852 run_test 187b "Test data version change on volatile file"
16853
16854 test_200() {
16855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16856         remote_mgs_nodsh && skip "remote MGS with nodsh"
16857         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16858
16859         local POOL=${POOL:-cea1}
16860         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16861         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16862         # Pool OST targets
16863         local first_ost=0
16864         local last_ost=$(($OSTCOUNT - 1))
16865         local ost_step=2
16866         local ost_list=$(seq $first_ost $ost_step $last_ost)
16867         local ost_range="$first_ost $last_ost $ost_step"
16868         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16869         local file_dir=$POOL_ROOT/file_tst
16870         local subdir=$test_path/subdir
16871         local rc=0
16872
16873         while : ; do
16874                 # former test_200a test_200b
16875                 pool_add $POOL                          || { rc=$? ; break; }
16876                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16877                 # former test_200c test_200d
16878                 mkdir -p $test_path
16879                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16880                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16881                 mkdir -p $subdir
16882                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16883                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16884                                                         || { rc=$? ; break; }
16885                 # former test_200e test_200f
16886                 local files=$((OSTCOUNT*3))
16887                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16888                                                         || { rc=$? ; break; }
16889                 pool_create_files $POOL $file_dir $files "$ost_list" \
16890                                                         || { rc=$? ; break; }
16891                 # former test_200g test_200h
16892                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16893                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16894
16895                 # former test_201a test_201b test_201c
16896                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16897
16898                 local f=$test_path/$tfile
16899                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16900                 pool_remove $POOL $f                    || { rc=$? ; break; }
16901                 break
16902         done
16903
16904         destroy_test_pools
16905
16906         return $rc
16907 }
16908 run_test 200 "OST pools"
16909
16910 # usage: default_attr <count | size | offset>
16911 default_attr() {
16912         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16913 }
16914
16915 # usage: check_default_stripe_attr
16916 check_default_stripe_attr() {
16917         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16918         case $1 in
16919         --stripe-count|-c)
16920                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16921         --stripe-size|-S)
16922                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16923         --stripe-index|-i)
16924                 EXPECTED=-1;;
16925         *)
16926                 error "unknown getstripe attr '$1'"
16927         esac
16928
16929         [ $ACTUAL == $EXPECTED ] ||
16930                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16931 }
16932
16933 test_204a() {
16934         test_mkdir $DIR/$tdir
16935         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16936
16937         check_default_stripe_attr --stripe-count
16938         check_default_stripe_attr --stripe-size
16939         check_default_stripe_attr --stripe-index
16940 }
16941 run_test 204a "Print default stripe attributes"
16942
16943 test_204b() {
16944         test_mkdir $DIR/$tdir
16945         $LFS setstripe --stripe-count 1 $DIR/$tdir
16946
16947         check_default_stripe_attr --stripe-size
16948         check_default_stripe_attr --stripe-index
16949 }
16950 run_test 204b "Print default stripe size and offset"
16951
16952 test_204c() {
16953         test_mkdir $DIR/$tdir
16954         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16955
16956         check_default_stripe_attr --stripe-count
16957         check_default_stripe_attr --stripe-index
16958 }
16959 run_test 204c "Print default stripe count and offset"
16960
16961 test_204d() {
16962         test_mkdir $DIR/$tdir
16963         $LFS setstripe --stripe-index 0 $DIR/$tdir
16964
16965         check_default_stripe_attr --stripe-count
16966         check_default_stripe_attr --stripe-size
16967 }
16968 run_test 204d "Print default stripe count and size"
16969
16970 test_204e() {
16971         test_mkdir $DIR/$tdir
16972         $LFS setstripe -d $DIR/$tdir
16973
16974         check_default_stripe_attr --stripe-count --raw
16975         check_default_stripe_attr --stripe-size --raw
16976         check_default_stripe_attr --stripe-index --raw
16977 }
16978 run_test 204e "Print raw stripe attributes"
16979
16980 test_204f() {
16981         test_mkdir $DIR/$tdir
16982         $LFS setstripe --stripe-count 1 $DIR/$tdir
16983
16984         check_default_stripe_attr --stripe-size --raw
16985         check_default_stripe_attr --stripe-index --raw
16986 }
16987 run_test 204f "Print raw stripe size and offset"
16988
16989 test_204g() {
16990         test_mkdir $DIR/$tdir
16991         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16992
16993         check_default_stripe_attr --stripe-count --raw
16994         check_default_stripe_attr --stripe-index --raw
16995 }
16996 run_test 204g "Print raw stripe count and offset"
16997
16998 test_204h() {
16999         test_mkdir $DIR/$tdir
17000         $LFS setstripe --stripe-index 0 $DIR/$tdir
17001
17002         check_default_stripe_attr --stripe-count --raw
17003         check_default_stripe_attr --stripe-size --raw
17004 }
17005 run_test 204h "Print raw stripe count and size"
17006
17007 # Figure out which job scheduler is being used, if any,
17008 # or use a fake one
17009 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17010         JOBENV=SLURM_JOB_ID
17011 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17012         JOBENV=LSB_JOBID
17013 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17014         JOBENV=PBS_JOBID
17015 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17016         JOBENV=LOADL_STEP_ID
17017 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17018         JOBENV=JOB_ID
17019 else
17020         $LCTL list_param jobid_name > /dev/null 2>&1
17021         if [ $? -eq 0 ]; then
17022                 JOBENV=nodelocal
17023         else
17024                 JOBENV=FAKE_JOBID
17025         fi
17026 fi
17027 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17028
17029 verify_jobstats() {
17030         local cmd=($1)
17031         shift
17032         local facets="$@"
17033
17034 # we don't really need to clear the stats for this test to work, since each
17035 # command has a unique jobid, but it makes debugging easier if needed.
17036 #       for facet in $facets; do
17037 #               local dev=$(convert_facet2label $facet)
17038 #               # clear old jobstats
17039 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17040 #       done
17041
17042         # use a new JobID for each test, or we might see an old one
17043         [ "$JOBENV" = "FAKE_JOBID" ] &&
17044                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17045
17046         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17047
17048         [ "$JOBENV" = "nodelocal" ] && {
17049                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17050                 $LCTL set_param jobid_name=$FAKE_JOBID
17051                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17052         }
17053
17054         log "Test: ${cmd[*]}"
17055         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17056
17057         if [ $JOBENV = "FAKE_JOBID" ]; then
17058                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17059         else
17060                 ${cmd[*]}
17061         fi
17062
17063         # all files are created on OST0000
17064         for facet in $facets; do
17065                 local stats="*.$(convert_facet2label $facet).job_stats"
17066
17067                 # strip out libtool wrappers for in-tree executables
17068                 if [ $(do_facet $facet lctl get_param $stats |
17069                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17070                         do_facet $facet lctl get_param $stats
17071                         error "No jobstats for $JOBVAL found on $facet::$stats"
17072                 fi
17073         done
17074 }
17075
17076 jobstats_set() {
17077         local new_jobenv=$1
17078
17079         set_persistent_param_and_check client "jobid_var" \
17080                 "$FSNAME.sys.jobid_var" $new_jobenv
17081 }
17082
17083 test_205a() { # Job stats
17084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17085         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17086                 skip "Need MDS version with at least 2.7.1"
17087         remote_mgs_nodsh && skip "remote MGS with nodsh"
17088         remote_mds_nodsh && skip "remote MDS with nodsh"
17089         remote_ost_nodsh && skip "remote OST with nodsh"
17090         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17091                 skip "Server doesn't support jobstats"
17092         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17093
17094         local old_jobenv=$($LCTL get_param -n jobid_var)
17095         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17096
17097         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17098                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17099         else
17100                 stack_trap "do_facet mgs $PERM_CMD \
17101                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17102         fi
17103         changelog_register
17104
17105         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17106                                 mdt.*.job_cleanup_interval | head -n 1)
17107         local new_interval=5
17108         do_facet $SINGLEMDS \
17109                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17110         stack_trap "do_facet $SINGLEMDS \
17111                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17112         local start=$SECONDS
17113
17114         local cmd
17115         # mkdir
17116         cmd="mkdir $DIR/$tdir"
17117         verify_jobstats "$cmd" "$SINGLEMDS"
17118         # rmdir
17119         cmd="rmdir $DIR/$tdir"
17120         verify_jobstats "$cmd" "$SINGLEMDS"
17121         # mkdir on secondary MDT
17122         if [ $MDSCOUNT -gt 1 ]; then
17123                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17124                 verify_jobstats "$cmd" "mds2"
17125         fi
17126         # mknod
17127         cmd="mknod $DIR/$tfile c 1 3"
17128         verify_jobstats "$cmd" "$SINGLEMDS"
17129         # unlink
17130         cmd="rm -f $DIR/$tfile"
17131         verify_jobstats "$cmd" "$SINGLEMDS"
17132         # create all files on OST0000 so verify_jobstats can find OST stats
17133         # open & close
17134         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17135         verify_jobstats "$cmd" "$SINGLEMDS"
17136         # setattr
17137         cmd="touch $DIR/$tfile"
17138         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17139         # write
17140         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17141         verify_jobstats "$cmd" "ost1"
17142         # read
17143         cancel_lru_locks osc
17144         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17145         verify_jobstats "$cmd" "ost1"
17146         # truncate
17147         cmd="$TRUNCATE $DIR/$tfile 0"
17148         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17149         # rename
17150         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17151         verify_jobstats "$cmd" "$SINGLEMDS"
17152         # jobstats expiry - sleep until old stats should be expired
17153         local left=$((new_interval + 5 - (SECONDS - start)))
17154         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17155                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17156                         "0" $left
17157         cmd="mkdir $DIR/$tdir.expire"
17158         verify_jobstats "$cmd" "$SINGLEMDS"
17159         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17160             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17161
17162         # Ensure that jobid are present in changelog (if supported by MDS)
17163         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17164                 changelog_dump | tail -10
17165                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17166                 [ $jobids -eq 9 ] ||
17167                         error "Wrong changelog jobid count $jobids != 9"
17168
17169                 # LU-5862
17170                 JOBENV="disable"
17171                 jobstats_set $JOBENV
17172                 touch $DIR/$tfile
17173                 changelog_dump | grep $tfile
17174                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17175                 [ $jobids -eq 0 ] ||
17176                         error "Unexpected jobids when jobid_var=$JOBENV"
17177         fi
17178
17179         # test '%j' access to environment variable - if supported
17180         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17181                 JOBENV="JOBCOMPLEX"
17182                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17183
17184                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17185         fi
17186
17187         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17188                 JOBENV="JOBCOMPLEX"
17189                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17190
17191                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17192         fi
17193
17194         # test '%j' access to per-session jobid - if supported
17195         if lctl list_param jobid_this_session > /dev/null 2>&1
17196         then
17197                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17198                 lctl set_param jobid_this_session=$USER
17199
17200                 JOBENV="JOBCOMPLEX"
17201                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17202
17203                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17204         fi
17205 }
17206 run_test 205a "Verify job stats"
17207
17208 # LU-13117, LU-13597
17209 test_205b() {
17210         job_stats="mdt.*.job_stats"
17211         $LCTL set_param $job_stats=clear
17212         # Setting jobid_var to USER might not be supported
17213         $LCTL set_param jobid_var=USER || true
17214         $LCTL set_param jobid_name="%e.%u"
17215         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17216         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17217                 grep "job_id:.*foolish" &&
17218                         error "Unexpected jobid found"
17219         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17220                 grep "open:.*min.*max.*sum" ||
17221                         error "wrong job_stats format found"
17222 }
17223 run_test 205b "Verify job stats jobid and output format"
17224
17225 # LU-13733
17226 test_205c() {
17227         $LCTL set_param llite.*.stats=0
17228         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17229         $LCTL get_param llite.*.stats
17230         $LCTL get_param llite.*.stats | grep \
17231                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17232                         error "wrong client stats format found"
17233 }
17234 run_test 205c "Verify client stats format"
17235
17236 # LU-1480, LU-1773 and LU-1657
17237 test_206() {
17238         mkdir -p $DIR/$tdir
17239         $LFS setstripe -c -1 $DIR/$tdir
17240 #define OBD_FAIL_LOV_INIT 0x1403
17241         $LCTL set_param fail_loc=0xa0001403
17242         $LCTL set_param fail_val=1
17243         touch $DIR/$tdir/$tfile || true
17244 }
17245 run_test 206 "fail lov_init_raid0() doesn't lbug"
17246
17247 test_207a() {
17248         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17249         local fsz=`stat -c %s $DIR/$tfile`
17250         cancel_lru_locks mdc
17251
17252         # do not return layout in getattr intent
17253 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17254         $LCTL set_param fail_loc=0x170
17255         local sz=`stat -c %s $DIR/$tfile`
17256
17257         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17258
17259         rm -rf $DIR/$tfile
17260 }
17261 run_test 207a "can refresh layout at glimpse"
17262
17263 test_207b() {
17264         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17265         local cksum=`md5sum $DIR/$tfile`
17266         local fsz=`stat -c %s $DIR/$tfile`
17267         cancel_lru_locks mdc
17268         cancel_lru_locks osc
17269
17270         # do not return layout in getattr intent
17271 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17272         $LCTL set_param fail_loc=0x171
17273
17274         # it will refresh layout after the file is opened but before read issues
17275         echo checksum is "$cksum"
17276         echo "$cksum" |md5sum -c --quiet || error "file differs"
17277
17278         rm -rf $DIR/$tfile
17279 }
17280 run_test 207b "can refresh layout at open"
17281
17282 test_208() {
17283         # FIXME: in this test suite, only RD lease is used. This is okay
17284         # for now as only exclusive open is supported. After generic lease
17285         # is done, this test suite should be revised. - Jinshan
17286
17287         remote_mds_nodsh && skip "remote MDS with nodsh"
17288         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17289                 skip "Need MDS version at least 2.4.52"
17290
17291         echo "==== test 1: verify get lease work"
17292         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17293
17294         echo "==== test 2: verify lease can be broken by upcoming open"
17295         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17296         local PID=$!
17297         sleep 1
17298
17299         $MULTIOP $DIR/$tfile oO_RDONLY:c
17300         kill -USR1 $PID && wait $PID || error "break lease error"
17301
17302         echo "==== test 3: verify lease can't be granted if an open already exists"
17303         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17304         local PID=$!
17305         sleep 1
17306
17307         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17308         kill -USR1 $PID && wait $PID || error "open file error"
17309
17310         echo "==== test 4: lease can sustain over recovery"
17311         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17312         PID=$!
17313         sleep 1
17314
17315         fail mds1
17316
17317         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17318
17319         echo "==== test 5: lease broken can't be regained by replay"
17320         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17321         PID=$!
17322         sleep 1
17323
17324         # open file to break lease and then recovery
17325         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17326         fail mds1
17327
17328         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17329
17330         rm -f $DIR/$tfile
17331 }
17332 run_test 208 "Exclusive open"
17333
17334 test_209() {
17335         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17336                 skip_env "must have disp_stripe"
17337
17338         touch $DIR/$tfile
17339         sync; sleep 5; sync;
17340
17341         echo 3 > /proc/sys/vm/drop_caches
17342         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17343                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17344         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17345
17346         # open/close 500 times
17347         for i in $(seq 500); do
17348                 cat $DIR/$tfile
17349         done
17350
17351         echo 3 > /proc/sys/vm/drop_caches
17352         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17353                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17354         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17355
17356         echo "before: $req_before, after: $req_after"
17357         [ $((req_after - req_before)) -ge 300 ] &&
17358                 error "open/close requests are not freed"
17359         return 0
17360 }
17361 run_test 209 "read-only open/close requests should be freed promptly"
17362
17363 test_210() {
17364         local pid
17365
17366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17367         pid=$!
17368         sleep 1
17369
17370         $LFS getstripe $DIR/$tfile
17371         kill -USR1 $pid
17372         wait $pid || error "multiop failed"
17373
17374         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17375         pid=$!
17376         sleep 1
17377
17378         $LFS getstripe $DIR/$tfile
17379         kill -USR1 $pid
17380         wait $pid || error "multiop failed"
17381 }
17382 run_test 210 "lfs getstripe does not break leases"
17383
17384 test_212() {
17385         size=`date +%s`
17386         size=$((size % 8192 + 1))
17387         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17388         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17389         rm -f $DIR/f212 $DIR/f212.xyz
17390 }
17391 run_test 212 "Sendfile test ============================================"
17392
17393 test_213() {
17394         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17395         cancel_lru_locks osc
17396         lctl set_param fail_loc=0x8000040f
17397         # generate a read lock
17398         cat $DIR/$tfile > /dev/null
17399         # write to the file, it will try to cancel the above read lock.
17400         cat /etc/hosts >> $DIR/$tfile
17401 }
17402 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17403
17404 test_214() { # for bug 20133
17405         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17406         for (( i=0; i < 340; i++ )) ; do
17407                 touch $DIR/$tdir/d214c/a$i
17408         done
17409
17410         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17411         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17412         ls $DIR/d214c || error "ls $DIR/d214c failed"
17413         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17414         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17415 }
17416 run_test 214 "hash-indexed directory test - bug 20133"
17417
17418 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17419 create_lnet_proc_files() {
17420         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17421 }
17422
17423 # counterpart of create_lnet_proc_files
17424 remove_lnet_proc_files() {
17425         rm -f $TMP/lnet_$1.sys
17426 }
17427
17428 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17429 # 3rd arg as regexp for body
17430 check_lnet_proc_stats() {
17431         local l=$(cat "$TMP/lnet_$1" |wc -l)
17432         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17433
17434         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17435 }
17436
17437 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17438 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17439 # optional and can be regexp for 2nd line (lnet.routes case)
17440 check_lnet_proc_entry() {
17441         local blp=2          # blp stands for 'position of 1st line of body'
17442         [ -z "$5" ] || blp=3 # lnet.routes case
17443
17444         local l=$(cat "$TMP/lnet_$1" |wc -l)
17445         # subtracting one from $blp because the body can be empty
17446         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17447
17448         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17449                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17450
17451         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17452                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17453
17454         # bail out if any unexpected line happened
17455         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17456         [ "$?" != 0 ] || error "$2 misformatted"
17457 }
17458
17459 test_215() { # for bugs 18102, 21079, 21517
17460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17461
17462         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17463         local P='[1-9][0-9]*'           # positive numeric
17464         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17465         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17466         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17467         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17468
17469         local L1 # regexp for 1st line
17470         local L2 # regexp for 2nd line (optional)
17471         local BR # regexp for the rest (body)
17472
17473         # lnet.stats should look as 11 space-separated non-negative numerics
17474         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17475         create_lnet_proc_files "stats"
17476         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17477         remove_lnet_proc_files "stats"
17478
17479         # lnet.routes should look like this:
17480         # Routing disabled/enabled
17481         # net hops priority state router
17482         # where net is a string like tcp0, hops > 0, priority >= 0,
17483         # state is up/down,
17484         # router is a string like 192.168.1.1@tcp2
17485         L1="^Routing (disabled|enabled)$"
17486         L2="^net +hops +priority +state +router$"
17487         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17488         create_lnet_proc_files "routes"
17489         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17490         remove_lnet_proc_files "routes"
17491
17492         # lnet.routers should look like this:
17493         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17494         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17495         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17496         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17497         L1="^ref +rtr_ref +alive +router$"
17498         BR="^$P +$P +(up|down) +$NID$"
17499         create_lnet_proc_files "routers"
17500         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17501         remove_lnet_proc_files "routers"
17502
17503         # lnet.peers should look like this:
17504         # nid refs state last max rtr min tx min queue
17505         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17506         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17507         # numeric (0 or >0 or <0), queue >= 0.
17508         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17509         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17510         create_lnet_proc_files "peers"
17511         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17512         remove_lnet_proc_files "peers"
17513
17514         # lnet.buffers  should look like this:
17515         # pages count credits min
17516         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17517         L1="^pages +count +credits +min$"
17518         BR="^ +$N +$N +$I +$I$"
17519         create_lnet_proc_files "buffers"
17520         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17521         remove_lnet_proc_files "buffers"
17522
17523         # lnet.nis should look like this:
17524         # nid status alive refs peer rtr max tx min
17525         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17526         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17527         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17528         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17529         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17530         create_lnet_proc_files "nis"
17531         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17532         remove_lnet_proc_files "nis"
17533
17534         # can we successfully write to lnet.stats?
17535         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17536 }
17537 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17538
17539 test_216() { # bug 20317
17540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17541         remote_ost_nodsh && skip "remote OST with nodsh"
17542
17543         local node
17544         local facets=$(get_facets OST)
17545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17546
17547         save_lustre_params client "osc.*.contention_seconds" > $p
17548         save_lustre_params $facets \
17549                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17550         save_lustre_params $facets \
17551                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17552         save_lustre_params $facets \
17553                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17554         clear_stats osc.*.osc_stats
17555
17556         # agressive lockless i/o settings
17557         do_nodes $(comma_list $(osts_nodes)) \
17558                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17559                         ldlm.namespaces.filter-*.contended_locks=0 \
17560                         ldlm.namespaces.filter-*.contention_seconds=60"
17561         lctl set_param -n osc.*.contention_seconds=60
17562
17563         $DIRECTIO write $DIR/$tfile 0 10 4096
17564         $CHECKSTAT -s 40960 $DIR/$tfile
17565
17566         # disable lockless i/o
17567         do_nodes $(comma_list $(osts_nodes)) \
17568                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17569                         ldlm.namespaces.filter-*.contended_locks=32 \
17570                         ldlm.namespaces.filter-*.contention_seconds=0"
17571         lctl set_param -n osc.*.contention_seconds=0
17572         clear_stats osc.*.osc_stats
17573
17574         dd if=/dev/zero of=$DIR/$tfile count=0
17575         $CHECKSTAT -s 0 $DIR/$tfile
17576
17577         restore_lustre_params <$p
17578         rm -f $p
17579         rm $DIR/$tfile
17580 }
17581 run_test 216 "check lockless direct write updates file size and kms correctly"
17582
17583 test_217() { # bug 22430
17584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17585
17586         local node
17587         local nid
17588
17589         for node in $(nodes_list); do
17590                 nid=$(host_nids_address $node $NETTYPE)
17591                 if [[ $nid = *-* ]] ; then
17592                         echo "lctl ping $(h2nettype $nid)"
17593                         lctl ping $(h2nettype $nid)
17594                 else
17595                         echo "skipping $node (no hyphen detected)"
17596                 fi
17597         done
17598 }
17599 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17600
17601 test_218() {
17602        # do directio so as not to populate the page cache
17603        log "creating a 10 Mb file"
17604        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17605        log "starting reads"
17606        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17607        log "truncating the file"
17608        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17609        log "killing dd"
17610        kill %+ || true # reads might have finished
17611        echo "wait until dd is finished"
17612        wait
17613        log "removing the temporary file"
17614        rm -rf $DIR/$tfile || error "tmp file removal failed"
17615 }
17616 run_test 218 "parallel read and truncate should not deadlock"
17617
17618 test_219() {
17619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17620
17621         # write one partial page
17622         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17623         # set no grant so vvp_io_commit_write will do sync write
17624         $LCTL set_param fail_loc=0x411
17625         # write a full page at the end of file
17626         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17627
17628         $LCTL set_param fail_loc=0
17629         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17630         $LCTL set_param fail_loc=0x411
17631         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17632
17633         # LU-4201
17634         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17635         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17636 }
17637 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17638
17639 test_220() { #LU-325
17640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17641         remote_ost_nodsh && skip "remote OST with nodsh"
17642         remote_mds_nodsh && skip "remote MDS with nodsh"
17643         remote_mgs_nodsh && skip "remote MGS with nodsh"
17644
17645         local OSTIDX=0
17646
17647         # create on MDT0000 so the last_id and next_id are correct
17648         mkdir $DIR/$tdir
17649         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17650         OST=${OST%_UUID}
17651
17652         # on the mdt's osc
17653         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17654         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17655                         osp.$mdtosc_proc1.prealloc_last_id)
17656         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17657                         osp.$mdtosc_proc1.prealloc_next_id)
17658
17659         $LFS df -i
17660
17661         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17662         #define OBD_FAIL_OST_ENOINO              0x229
17663         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17664         create_pool $FSNAME.$TESTNAME || return 1
17665         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17666
17667         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17668
17669         MDSOBJS=$((last_id - next_id))
17670         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17671
17672         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17673         echo "OST still has $count kbytes free"
17674
17675         echo "create $MDSOBJS files @next_id..."
17676         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17677
17678         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17679                         osp.$mdtosc_proc1.prealloc_last_id)
17680         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17681                         osp.$mdtosc_proc1.prealloc_next_id)
17682
17683         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17684         $LFS df -i
17685
17686         echo "cleanup..."
17687
17688         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17689         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17690
17691         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17692                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17693         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17694                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17695         echo "unlink $MDSOBJS files @$next_id..."
17696         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17697 }
17698 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17699
17700 test_221() {
17701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17702
17703         dd if=`which date` of=$MOUNT/date oflag=sync
17704         chmod +x $MOUNT/date
17705
17706         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17707         $LCTL set_param fail_loc=0x80001401
17708
17709         $MOUNT/date > /dev/null
17710         rm -f $MOUNT/date
17711 }
17712 run_test 221 "make sure fault and truncate race to not cause OOM"
17713
17714 test_222a () {
17715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17716
17717         rm -rf $DIR/$tdir
17718         test_mkdir $DIR/$tdir
17719         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17720         createmany -o $DIR/$tdir/$tfile 10
17721         cancel_lru_locks mdc
17722         cancel_lru_locks osc
17723         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17724         $LCTL set_param fail_loc=0x31a
17725         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17726         $LCTL set_param fail_loc=0
17727         rm -r $DIR/$tdir
17728 }
17729 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17730
17731 test_222b () {
17732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17733
17734         rm -rf $DIR/$tdir
17735         test_mkdir $DIR/$tdir
17736         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17737         createmany -o $DIR/$tdir/$tfile 10
17738         cancel_lru_locks mdc
17739         cancel_lru_locks osc
17740         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17741         $LCTL set_param fail_loc=0x31a
17742         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17743         $LCTL set_param fail_loc=0
17744 }
17745 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17746
17747 test_223 () {
17748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17749
17750         rm -rf $DIR/$tdir
17751         test_mkdir $DIR/$tdir
17752         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17753         createmany -o $DIR/$tdir/$tfile 10
17754         cancel_lru_locks mdc
17755         cancel_lru_locks osc
17756         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17757         $LCTL set_param fail_loc=0x31b
17758         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17759         $LCTL set_param fail_loc=0
17760         rm -r $DIR/$tdir
17761 }
17762 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17763
17764 test_224a() { # LU-1039, MRP-303
17765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17766
17767         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17768         $LCTL set_param fail_loc=0x508
17769         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17770         $LCTL set_param fail_loc=0
17771         df $DIR
17772 }
17773 run_test 224a "Don't panic on bulk IO failure"
17774
17775 test_224b() { # LU-1039, MRP-303
17776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17777
17778         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17779         cancel_lru_locks osc
17780         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17781         $LCTL set_param fail_loc=0x515
17782         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17783         $LCTL set_param fail_loc=0
17784         df $DIR
17785 }
17786 run_test 224b "Don't panic on bulk IO failure"
17787
17788 test_224c() { # LU-6441
17789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17790         remote_mds_nodsh && skip "remote MDS with nodsh"
17791
17792         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17793         save_writethrough $p
17794         set_cache writethrough on
17795
17796         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17797         local at_max=$($LCTL get_param -n at_max)
17798         local timeout=$($LCTL get_param -n timeout)
17799         local test_at="at_max"
17800         local param_at="$FSNAME.sys.at_max"
17801         local test_timeout="timeout"
17802         local param_timeout="$FSNAME.sys.timeout"
17803
17804         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17805
17806         set_persistent_param_and_check client "$test_at" "$param_at" 0
17807         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17808
17809         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17810         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17811         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17812         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17813         sync
17814         do_facet ost1 "$LCTL set_param fail_loc=0"
17815
17816         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17817         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17818                 $timeout
17819
17820         $LCTL set_param -n $pages_per_rpc
17821         restore_lustre_params < $p
17822         rm -f $p
17823 }
17824 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17825
17826 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17827 test_225a () {
17828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17829         if [ -z ${MDSSURVEY} ]; then
17830                 skip_env "mds-survey not found"
17831         fi
17832         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17833                 skip "Need MDS version at least 2.2.51"
17834
17835         local mds=$(facet_host $SINGLEMDS)
17836         local target=$(do_nodes $mds 'lctl dl' |
17837                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17838
17839         local cmd1="file_count=1000 thrhi=4"
17840         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17841         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17842         local cmd="$cmd1 $cmd2 $cmd3"
17843
17844         rm -f ${TMP}/mds_survey*
17845         echo + $cmd
17846         eval $cmd || error "mds-survey with zero-stripe failed"
17847         cat ${TMP}/mds_survey*
17848         rm -f ${TMP}/mds_survey*
17849 }
17850 run_test 225a "Metadata survey sanity with zero-stripe"
17851
17852 test_225b () {
17853         if [ -z ${MDSSURVEY} ]; then
17854                 skip_env "mds-survey not found"
17855         fi
17856         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17857                 skip "Need MDS version at least 2.2.51"
17858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17859         remote_mds_nodsh && skip "remote MDS with nodsh"
17860         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17861                 skip_env "Need to mount OST to test"
17862         fi
17863
17864         local mds=$(facet_host $SINGLEMDS)
17865         local target=$(do_nodes $mds 'lctl dl' |
17866                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17867
17868         local cmd1="file_count=1000 thrhi=4"
17869         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17870         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17871         local cmd="$cmd1 $cmd2 $cmd3"
17872
17873         rm -f ${TMP}/mds_survey*
17874         echo + $cmd
17875         eval $cmd || error "mds-survey with stripe_count failed"
17876         cat ${TMP}/mds_survey*
17877         rm -f ${TMP}/mds_survey*
17878 }
17879 run_test 225b "Metadata survey sanity with stripe_count = 1"
17880
17881 mcreate_path2fid () {
17882         local mode=$1
17883         local major=$2
17884         local minor=$3
17885         local name=$4
17886         local desc=$5
17887         local path=$DIR/$tdir/$name
17888         local fid
17889         local rc
17890         local fid_path
17891
17892         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17893                 error "cannot create $desc"
17894
17895         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17896         rc=$?
17897         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17898
17899         fid_path=$($LFS fid2path $MOUNT $fid)
17900         rc=$?
17901         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17902
17903         [ "$path" == "$fid_path" ] ||
17904                 error "fid2path returned $fid_path, expected $path"
17905
17906         echo "pass with $path and $fid"
17907 }
17908
17909 test_226a () {
17910         rm -rf $DIR/$tdir
17911         mkdir -p $DIR/$tdir
17912
17913         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17914         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17915         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17916         mcreate_path2fid 0040666 0 0 dir "directory"
17917         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17918         mcreate_path2fid 0100666 0 0 file "regular file"
17919         mcreate_path2fid 0120666 0 0 link "symbolic link"
17920         mcreate_path2fid 0140666 0 0 sock "socket"
17921 }
17922 run_test 226a "call path2fid and fid2path on files of all type"
17923
17924 test_226b () {
17925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17926
17927         local MDTIDX=1
17928
17929         rm -rf $DIR/$tdir
17930         mkdir -p $DIR/$tdir
17931         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17932                 error "create remote directory failed"
17933         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17934         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17935                                 "character special file (null)"
17936         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17937                                 "character special file (no device)"
17938         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17939         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17940                                 "block special file (loop)"
17941         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17942         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17943         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17944 }
17945 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17946
17947 test_226c () {
17948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17949         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17950                 skip "Need MDS version at least 2.13.55"
17951
17952         local submnt=/mnt/submnt
17953         local srcfile=/etc/passwd
17954         local dstfile=$submnt/passwd
17955         local path
17956         local fid
17957
17958         rm -rf $DIR/$tdir
17959         rm -rf $submnt
17960         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17961                 error "create remote directory failed"
17962         mkdir -p $submnt || error "create $submnt failed"
17963         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17964                 error "mount $submnt failed"
17965         stack_trap "umount $submnt" EXIT
17966
17967         cp $srcfile $dstfile
17968         fid=$($LFS path2fid $dstfile)
17969         path=$($LFS fid2path $submnt "$fid")
17970         [ "$path" = "$dstfile" ] ||
17971                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17972 }
17973 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17974
17975 # LU-1299 Executing or running ldd on a truncated executable does not
17976 # cause an out-of-memory condition.
17977 test_227() {
17978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17979         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17980
17981         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17982         chmod +x $MOUNT/date
17983
17984         $MOUNT/date > /dev/null
17985         ldd $MOUNT/date > /dev/null
17986         rm -f $MOUNT/date
17987 }
17988 run_test 227 "running truncated executable does not cause OOM"
17989
17990 # LU-1512 try to reuse idle OI blocks
17991 test_228a() {
17992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17993         remote_mds_nodsh && skip "remote MDS with nodsh"
17994         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17995
17996         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17997         local myDIR=$DIR/$tdir
17998
17999         mkdir -p $myDIR
18000         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18001         $LCTL set_param fail_loc=0x80001002
18002         createmany -o $myDIR/t- 10000
18003         $LCTL set_param fail_loc=0
18004         # The guard is current the largest FID holder
18005         touch $myDIR/guard
18006         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18007                     tr -d '[')
18008         local IDX=$(($SEQ % 64))
18009
18010         do_facet $SINGLEMDS sync
18011         # Make sure journal flushed.
18012         sleep 6
18013         local blk1=$(do_facet $SINGLEMDS \
18014                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18015                      grep Blockcount | awk '{print $4}')
18016
18017         # Remove old files, some OI blocks will become idle.
18018         unlinkmany $myDIR/t- 10000
18019         # Create new files, idle OI blocks should be reused.
18020         createmany -o $myDIR/t- 2000
18021         do_facet $SINGLEMDS sync
18022         # Make sure journal flushed.
18023         sleep 6
18024         local blk2=$(do_facet $SINGLEMDS \
18025                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18026                      grep Blockcount | awk '{print $4}')
18027
18028         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18029 }
18030 run_test 228a "try to reuse idle OI blocks"
18031
18032 test_228b() {
18033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18034         remote_mds_nodsh && skip "remote MDS with nodsh"
18035         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18036
18037         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18038         local myDIR=$DIR/$tdir
18039
18040         mkdir -p $myDIR
18041         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18042         $LCTL set_param fail_loc=0x80001002
18043         createmany -o $myDIR/t- 10000
18044         $LCTL set_param fail_loc=0
18045         # The guard is current the largest FID holder
18046         touch $myDIR/guard
18047         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18048                     tr -d '[')
18049         local IDX=$(($SEQ % 64))
18050
18051         do_facet $SINGLEMDS sync
18052         # Make sure journal flushed.
18053         sleep 6
18054         local blk1=$(do_facet $SINGLEMDS \
18055                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18056                      grep Blockcount | awk '{print $4}')
18057
18058         # Remove old files, some OI blocks will become idle.
18059         unlinkmany $myDIR/t- 10000
18060
18061         # stop the MDT
18062         stop $SINGLEMDS || error "Fail to stop MDT."
18063         # remount the MDT
18064         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18065
18066         df $MOUNT || error "Fail to df."
18067         # Create new files, idle OI blocks should be reused.
18068         createmany -o $myDIR/t- 2000
18069         do_facet $SINGLEMDS sync
18070         # Make sure journal flushed.
18071         sleep 6
18072         local blk2=$(do_facet $SINGLEMDS \
18073                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18074                      grep Blockcount | awk '{print $4}')
18075
18076         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18077 }
18078 run_test 228b "idle OI blocks can be reused after MDT restart"
18079
18080 #LU-1881
18081 test_228c() {
18082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18083         remote_mds_nodsh && skip "remote MDS with nodsh"
18084         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18085
18086         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18087         local myDIR=$DIR/$tdir
18088
18089         mkdir -p $myDIR
18090         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18091         $LCTL set_param fail_loc=0x80001002
18092         # 20000 files can guarantee there are index nodes in the OI file
18093         createmany -o $myDIR/t- 20000
18094         $LCTL set_param fail_loc=0
18095         # The guard is current the largest FID holder
18096         touch $myDIR/guard
18097         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18098                     tr -d '[')
18099         local IDX=$(($SEQ % 64))
18100
18101         do_facet $SINGLEMDS sync
18102         # Make sure journal flushed.
18103         sleep 6
18104         local blk1=$(do_facet $SINGLEMDS \
18105                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18106                      grep Blockcount | awk '{print $4}')
18107
18108         # Remove old files, some OI blocks will become idle.
18109         unlinkmany $myDIR/t- 20000
18110         rm -f $myDIR/guard
18111         # The OI file should become empty now
18112
18113         # Create new files, idle OI blocks should be reused.
18114         createmany -o $myDIR/t- 2000
18115         do_facet $SINGLEMDS sync
18116         # Make sure journal flushed.
18117         sleep 6
18118         local blk2=$(do_facet $SINGLEMDS \
18119                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18120                      grep Blockcount | awk '{print $4}')
18121
18122         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18123 }
18124 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18125
18126 test_229() { # LU-2482, LU-3448
18127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18128         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18129         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18130                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18131
18132         rm -f $DIR/$tfile
18133
18134         # Create a file with a released layout and stripe count 2.
18135         $MULTIOP $DIR/$tfile H2c ||
18136                 error "failed to create file with released layout"
18137
18138         $LFS getstripe -v $DIR/$tfile
18139
18140         local pattern=$($LFS getstripe -L $DIR/$tfile)
18141         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18142
18143         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18144                 error "getstripe"
18145         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18146         stat $DIR/$tfile || error "failed to stat released file"
18147
18148         chown $RUNAS_ID $DIR/$tfile ||
18149                 error "chown $RUNAS_ID $DIR/$tfile failed"
18150
18151         chgrp $RUNAS_ID $DIR/$tfile ||
18152                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18153
18154         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18155         rm $DIR/$tfile || error "failed to remove released file"
18156 }
18157 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18158
18159 test_230a() {
18160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18161         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18162         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18163                 skip "Need MDS version at least 2.11.52"
18164
18165         local MDTIDX=1
18166
18167         test_mkdir $DIR/$tdir
18168         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18169         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18170         [ $mdt_idx -ne 0 ] &&
18171                 error "create local directory on wrong MDT $mdt_idx"
18172
18173         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18174                         error "create remote directory failed"
18175         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18176         [ $mdt_idx -ne $MDTIDX ] &&
18177                 error "create remote directory on wrong MDT $mdt_idx"
18178
18179         createmany -o $DIR/$tdir/test_230/t- 10 ||
18180                 error "create files on remote directory failed"
18181         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18182         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18183         rm -r $DIR/$tdir || error "unlink remote directory failed"
18184 }
18185 run_test 230a "Create remote directory and files under the remote directory"
18186
18187 test_230b() {
18188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18190         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18191                 skip "Need MDS version at least 2.11.52"
18192
18193         local MDTIDX=1
18194         local mdt_index
18195         local i
18196         local file
18197         local pid
18198         local stripe_count
18199         local migrate_dir=$DIR/$tdir/migrate_dir
18200         local other_dir=$DIR/$tdir/other_dir
18201
18202         test_mkdir $DIR/$tdir
18203         test_mkdir -i0 -c1 $migrate_dir
18204         test_mkdir -i0 -c1 $other_dir
18205         for ((i=0; i<10; i++)); do
18206                 mkdir -p $migrate_dir/dir_${i}
18207                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18208                         error "create files under remote dir failed $i"
18209         done
18210
18211         cp /etc/passwd $migrate_dir/$tfile
18212         cp /etc/passwd $other_dir/$tfile
18213         chattr +SAD $migrate_dir
18214         chattr +SAD $migrate_dir/$tfile
18215
18216         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18217         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18218         local old_dir_mode=$(stat -c%f $migrate_dir)
18219         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18220
18221         mkdir -p $migrate_dir/dir_default_stripe2
18222         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18223         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18224
18225         mkdir -p $other_dir
18226         ln $migrate_dir/$tfile $other_dir/luna
18227         ln $migrate_dir/$tfile $migrate_dir/sofia
18228         ln $other_dir/$tfile $migrate_dir/david
18229         ln -s $migrate_dir/$tfile $other_dir/zachary
18230         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18231         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18232
18233         local len
18234         local lnktgt
18235
18236         # inline symlink
18237         for len in 58 59 60; do
18238                 lnktgt=$(str_repeat 'l' $len)
18239                 touch $migrate_dir/$lnktgt
18240                 ln -s $lnktgt $migrate_dir/${len}char_ln
18241         done
18242
18243         # PATH_MAX
18244         for len in 4094 4095; do
18245                 lnktgt=$(str_repeat 'l' $len)
18246                 ln -s $lnktgt $migrate_dir/${len}char_ln
18247         done
18248
18249         # NAME_MAX
18250         for len in 254 255; do
18251                 touch $migrate_dir/$(str_repeat 'l' $len)
18252         done
18253
18254         $LFS migrate -m $MDTIDX $migrate_dir ||
18255                 error "fails on migrating remote dir to MDT1"
18256
18257         echo "migratate to MDT1, then checking.."
18258         for ((i = 0; i < 10; i++)); do
18259                 for file in $(find $migrate_dir/dir_${i}); do
18260                         mdt_index=$($LFS getstripe -m $file)
18261                         # broken symlink getstripe will fail
18262                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18263                                 error "$file is not on MDT${MDTIDX}"
18264                 done
18265         done
18266
18267         # the multiple link file should still in MDT0
18268         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18269         [ $mdt_index == 0 ] ||
18270                 error "$file is not on MDT${MDTIDX}"
18271
18272         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18273         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18274                 error " expect $old_dir_flag get $new_dir_flag"
18275
18276         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18277         [ "$old_file_flag" = "$new_file_flag" ] ||
18278                 error " expect $old_file_flag get $new_file_flag"
18279
18280         local new_dir_mode=$(stat -c%f $migrate_dir)
18281         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18282                 error "expect mode $old_dir_mode get $new_dir_mode"
18283
18284         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18285         [ "$old_file_mode" = "$new_file_mode" ] ||
18286                 error "expect mode $old_file_mode get $new_file_mode"
18287
18288         diff /etc/passwd $migrate_dir/$tfile ||
18289                 error "$tfile different after migration"
18290
18291         diff /etc/passwd $other_dir/luna ||
18292                 error "luna different after migration"
18293
18294         diff /etc/passwd $migrate_dir/sofia ||
18295                 error "sofia different after migration"
18296
18297         diff /etc/passwd $migrate_dir/david ||
18298                 error "david different after migration"
18299
18300         diff /etc/passwd $other_dir/zachary ||
18301                 error "zachary different after migration"
18302
18303         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18304                 error "${tfile}_ln different after migration"
18305
18306         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18307                 error "${tfile}_ln_other different after migration"
18308
18309         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18310         [ $stripe_count = 2 ] ||
18311                 error "dir strpe_count $d != 2 after migration."
18312
18313         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18314         [ $stripe_count = 2 ] ||
18315                 error "file strpe_count $d != 2 after migration."
18316
18317         #migrate back to MDT0
18318         MDTIDX=0
18319
18320         $LFS migrate -m $MDTIDX $migrate_dir ||
18321                 error "fails on migrating remote dir to MDT0"
18322
18323         echo "migrate back to MDT0, checking.."
18324         for file in $(find $migrate_dir); do
18325                 mdt_index=$($LFS getstripe -m $file)
18326                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18327                         error "$file is not on MDT${MDTIDX}"
18328         done
18329
18330         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18331         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18332                 error " expect $old_dir_flag get $new_dir_flag"
18333
18334         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18335         [ "$old_file_flag" = "$new_file_flag" ] ||
18336                 error " expect $old_file_flag get $new_file_flag"
18337
18338         local new_dir_mode=$(stat -c%f $migrate_dir)
18339         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18340                 error "expect mode $old_dir_mode get $new_dir_mode"
18341
18342         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18343         [ "$old_file_mode" = "$new_file_mode" ] ||
18344                 error "expect mode $old_file_mode get $new_file_mode"
18345
18346         diff /etc/passwd ${migrate_dir}/$tfile ||
18347                 error "$tfile different after migration"
18348
18349         diff /etc/passwd ${other_dir}/luna ||
18350                 error "luna different after migration"
18351
18352         diff /etc/passwd ${migrate_dir}/sofia ||
18353                 error "sofia different after migration"
18354
18355         diff /etc/passwd ${other_dir}/zachary ||
18356                 error "zachary different after migration"
18357
18358         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18359                 error "${tfile}_ln different after migration"
18360
18361         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18362                 error "${tfile}_ln_other different after migration"
18363
18364         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18365         [ $stripe_count = 2 ] ||
18366                 error "dir strpe_count $d != 2 after migration."
18367
18368         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18369         [ $stripe_count = 2 ] ||
18370                 error "file strpe_count $d != 2 after migration."
18371
18372         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18373 }
18374 run_test 230b "migrate directory"
18375
18376 test_230c() {
18377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18379         remote_mds_nodsh && skip "remote MDS with nodsh"
18380         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18381                 skip "Need MDS version at least 2.11.52"
18382
18383         local MDTIDX=1
18384         local total=3
18385         local mdt_index
18386         local file
18387         local migrate_dir=$DIR/$tdir/migrate_dir
18388
18389         #If migrating directory fails in the middle, all entries of
18390         #the directory is still accessiable.
18391         test_mkdir $DIR/$tdir
18392         test_mkdir -i0 -c1 $migrate_dir
18393         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18394         stat $migrate_dir
18395         createmany -o $migrate_dir/f $total ||
18396                 error "create files under ${migrate_dir} failed"
18397
18398         # fail after migrating top dir, and this will fail only once, so the
18399         # first sub file migration will fail (currently f3), others succeed.
18400         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18401         do_facet mds1 lctl set_param fail_loc=0x1801
18402         local t=$(ls $migrate_dir | wc -l)
18403         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18404                 error "migrate should fail"
18405         local u=$(ls $migrate_dir | wc -l)
18406         [ "$u" == "$t" ] || error "$u != $t during migration"
18407
18408         # add new dir/file should succeed
18409         mkdir $migrate_dir/dir ||
18410                 error "mkdir failed under migrating directory"
18411         touch $migrate_dir/file ||
18412                 error "create file failed under migrating directory"
18413
18414         # add file with existing name should fail
18415         for file in $migrate_dir/f*; do
18416                 stat $file > /dev/null || error "stat $file failed"
18417                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18418                         error "open(O_CREAT|O_EXCL) $file should fail"
18419                 $MULTIOP $file m && error "create $file should fail"
18420                 touch $DIR/$tdir/remote_dir/$tfile ||
18421                         error "touch $tfile failed"
18422                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18423                         error "link $file should fail"
18424                 mdt_index=$($LFS getstripe -m $file)
18425                 if [ $mdt_index == 0 ]; then
18426                         # file failed to migrate is not allowed to rename to
18427                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18428                                 error "rename to $file should fail"
18429                 else
18430                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18431                                 error "rename to $file failed"
18432                 fi
18433                 echo hello >> $file || error "write $file failed"
18434         done
18435
18436         # resume migration with different options should fail
18437         $LFS migrate -m 0 $migrate_dir &&
18438                 error "migrate -m 0 $migrate_dir should fail"
18439
18440         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18441                 error "migrate -c 2 $migrate_dir should fail"
18442
18443         # resume migration should succeed
18444         $LFS migrate -m $MDTIDX $migrate_dir ||
18445                 error "migrate $migrate_dir failed"
18446
18447         echo "Finish migration, then checking.."
18448         for file in $(find $migrate_dir); do
18449                 mdt_index=$($LFS getstripe -m $file)
18450                 [ $mdt_index == $MDTIDX ] ||
18451                         error "$file is not on MDT${MDTIDX}"
18452         done
18453
18454         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18455 }
18456 run_test 230c "check directory accessiblity if migration failed"
18457
18458 test_230d() {
18459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18461         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18462                 skip "Need MDS version at least 2.11.52"
18463         # LU-11235
18464         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18465
18466         local migrate_dir=$DIR/$tdir/migrate_dir
18467         local old_index
18468         local new_index
18469         local old_count
18470         local new_count
18471         local new_hash
18472         local mdt_index
18473         local i
18474         local j
18475
18476         old_index=$((RANDOM % MDSCOUNT))
18477         old_count=$((MDSCOUNT - old_index))
18478         new_index=$((RANDOM % MDSCOUNT))
18479         new_count=$((MDSCOUNT - new_index))
18480         new_hash=1 # for all_char
18481
18482         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18483         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18484
18485         test_mkdir $DIR/$tdir
18486         test_mkdir -i $old_index -c $old_count $migrate_dir
18487
18488         for ((i=0; i<100; i++)); do
18489                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18490                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18491                         error "create files under remote dir failed $i"
18492         done
18493
18494         echo -n "Migrate from MDT$old_index "
18495         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18496         echo -n "to MDT$new_index"
18497         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18498         echo
18499
18500         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18501         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18502                 error "migrate remote dir error"
18503
18504         echo "Finish migration, then checking.."
18505         for file in $(find $migrate_dir); do
18506                 mdt_index=$($LFS getstripe -m $file)
18507                 if [ $mdt_index -lt $new_index ] ||
18508                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18509                         error "$file is on MDT$mdt_index"
18510                 fi
18511         done
18512
18513         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18514 }
18515 run_test 230d "check migrate big directory"
18516
18517 test_230e() {
18518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18521                 skip "Need MDS version at least 2.11.52"
18522
18523         local i
18524         local j
18525         local a_fid
18526         local b_fid
18527
18528         mkdir -p $DIR/$tdir
18529         mkdir $DIR/$tdir/migrate_dir
18530         mkdir $DIR/$tdir/other_dir
18531         touch $DIR/$tdir/migrate_dir/a
18532         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18533         ls $DIR/$tdir/other_dir
18534
18535         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18536                 error "migrate dir fails"
18537
18538         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18539         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18540
18541         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18542         [ $mdt_index == 0 ] || error "a is not on MDT0"
18543
18544         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18545                 error "migrate dir fails"
18546
18547         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18548         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18549
18550         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18551         [ $mdt_index == 1 ] || error "a is not on MDT1"
18552
18553         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18554         [ $mdt_index == 1 ] || error "b is not on MDT1"
18555
18556         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18557         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18558
18559         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18560
18561         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18562 }
18563 run_test 230e "migrate mulitple local link files"
18564
18565 test_230f() {
18566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18568         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18569                 skip "Need MDS version at least 2.11.52"
18570
18571         local a_fid
18572         local ln_fid
18573
18574         mkdir -p $DIR/$tdir
18575         mkdir $DIR/$tdir/migrate_dir
18576         $LFS mkdir -i1 $DIR/$tdir/other_dir
18577         touch $DIR/$tdir/migrate_dir/a
18578         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18579         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18580         ls $DIR/$tdir/other_dir
18581
18582         # a should be migrated to MDT1, since no other links on MDT0
18583         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18584                 error "#1 migrate dir fails"
18585         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18586         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18587         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18588         [ $mdt_index == 1 ] || error "a is not on MDT1"
18589
18590         # a should stay on MDT1, because it is a mulitple link file
18591         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18592                 error "#2 migrate dir fails"
18593         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18594         [ $mdt_index == 1 ] || error "a is not on MDT1"
18595
18596         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18597                 error "#3 migrate dir fails"
18598
18599         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18600         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18601         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18602
18603         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18604         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18605
18606         # a should be migrated to MDT0, since no other links on MDT1
18607         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18608                 error "#4 migrate dir fails"
18609         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18610         [ $mdt_index == 0 ] || error "a is not on MDT0"
18611
18612         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18613 }
18614 run_test 230f "migrate mulitple remote link files"
18615
18616 test_230g() {
18617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18619         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18620                 skip "Need MDS version at least 2.11.52"
18621
18622         mkdir -p $DIR/$tdir/migrate_dir
18623
18624         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18625                 error "migrating dir to non-exist MDT succeeds"
18626         true
18627 }
18628 run_test 230g "migrate dir to non-exist MDT"
18629
18630 test_230h() {
18631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18633         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18634                 skip "Need MDS version at least 2.11.52"
18635
18636         local mdt_index
18637
18638         mkdir -p $DIR/$tdir/migrate_dir
18639
18640         $LFS migrate -m1 $DIR &&
18641                 error "migrating mountpoint1 should fail"
18642
18643         $LFS migrate -m1 $DIR/$tdir/.. &&
18644                 error "migrating mountpoint2 should fail"
18645
18646         # same as mv
18647         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18648                 error "migrating $tdir/migrate_dir/.. should fail"
18649
18650         true
18651 }
18652 run_test 230h "migrate .. and root"
18653
18654 test_230i() {
18655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18657         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18658                 skip "Need MDS version at least 2.11.52"
18659
18660         mkdir -p $DIR/$tdir/migrate_dir
18661
18662         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18663                 error "migration fails with a tailing slash"
18664
18665         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18666                 error "migration fails with two tailing slashes"
18667 }
18668 run_test 230i "lfs migrate -m tolerates trailing slashes"
18669
18670 test_230j() {
18671         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18672         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18673                 skip "Need MDS version at least 2.11.52"
18674
18675         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18676         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18677                 error "create $tfile failed"
18678         cat /etc/passwd > $DIR/$tdir/$tfile
18679
18680         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18681
18682         cmp /etc/passwd $DIR/$tdir/$tfile ||
18683                 error "DoM file mismatch after migration"
18684 }
18685 run_test 230j "DoM file data not changed after dir migration"
18686
18687 test_230k() {
18688         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18689         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18690                 skip "Need MDS version at least 2.11.56"
18691
18692         local total=20
18693         local files_on_starting_mdt=0
18694
18695         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18696         $LFS getdirstripe $DIR/$tdir
18697         for i in $(seq $total); do
18698                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18699                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18700                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18701         done
18702
18703         echo "$files_on_starting_mdt files on MDT0"
18704
18705         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18706         $LFS getdirstripe $DIR/$tdir
18707
18708         files_on_starting_mdt=0
18709         for i in $(seq $total); do
18710                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18711                         error "file $tfile.$i mismatch after migration"
18712                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18713                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18714         done
18715
18716         echo "$files_on_starting_mdt files on MDT1 after migration"
18717         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18718
18719         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18720         $LFS getdirstripe $DIR/$tdir
18721
18722         files_on_starting_mdt=0
18723         for i in $(seq $total); do
18724                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18725                         error "file $tfile.$i mismatch after 2nd migration"
18726                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18727                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18728         done
18729
18730         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18731         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18732
18733         true
18734 }
18735 run_test 230k "file data not changed after dir migration"
18736
18737 test_230l() {
18738         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18739         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18740                 skip "Need MDS version at least 2.11.56"
18741
18742         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18743         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18744                 error "create files under remote dir failed $i"
18745         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18746 }
18747 run_test 230l "readdir between MDTs won't crash"
18748
18749 test_230m() {
18750         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18751         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18752                 skip "Need MDS version at least 2.11.56"
18753
18754         local MDTIDX=1
18755         local mig_dir=$DIR/$tdir/migrate_dir
18756         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18757         local shortstr="b"
18758         local val
18759
18760         echo "Creating files and dirs with xattrs"
18761         test_mkdir $DIR/$tdir
18762         test_mkdir -i0 -c1 $mig_dir
18763         mkdir $mig_dir/dir
18764         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18765                 error "cannot set xattr attr1 on dir"
18766         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18767                 error "cannot set xattr attr2 on dir"
18768         touch $mig_dir/dir/f0
18769         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18770                 error "cannot set xattr attr1 on file"
18771         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18772                 error "cannot set xattr attr2 on file"
18773         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18774         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18775         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18776         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18777         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18778         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18779         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18780         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18781         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18782
18783         echo "Migrating to MDT1"
18784         $LFS migrate -m $MDTIDX $mig_dir ||
18785                 error "fails on migrating dir to MDT1"
18786
18787         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18788         echo "Checking xattrs"
18789         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18790         [ "$val" = $longstr ] ||
18791                 error "expecting xattr1 $longstr on dir, found $val"
18792         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18793         [ "$val" = $shortstr ] ||
18794                 error "expecting xattr2 $shortstr on dir, found $val"
18795         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18796         [ "$val" = $longstr ] ||
18797                 error "expecting xattr1 $longstr on file, found $val"
18798         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18799         [ "$val" = $shortstr ] ||
18800                 error "expecting xattr2 $shortstr on file, found $val"
18801 }
18802 run_test 230m "xattrs not changed after dir migration"
18803
18804 test_230n() {
18805         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18806         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18807                 skip "Need MDS version at least 2.13.53"
18808
18809         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18810         cat /etc/hosts > $DIR/$tdir/$tfile
18811         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18812         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18813
18814         cmp /etc/hosts $DIR/$tdir/$tfile ||
18815                 error "File data mismatch after migration"
18816 }
18817 run_test 230n "Dir migration with mirrored file"
18818
18819 test_230o() {
18820         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18821         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18822                 skip "Need MDS version at least 2.13.52"
18823
18824         local mdts=$(comma_list $(mdts_nodes))
18825         local timeout=100
18826         local restripe_status
18827         local delta
18828         local i
18829
18830         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18831
18832         # in case "crush" hash type is not set
18833         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18834
18835         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18836                            mdt.*MDT0000.enable_dir_restripe)
18837         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18838         stack_trap "do_nodes $mdts $LCTL set_param \
18839                     mdt.*.enable_dir_restripe=$restripe_status"
18840
18841         mkdir $DIR/$tdir
18842         createmany -m $DIR/$tdir/f 100 ||
18843                 error "create files under remote dir failed $i"
18844         createmany -d $DIR/$tdir/d 100 ||
18845                 error "create dirs under remote dir failed $i"
18846
18847         for i in $(seq 2 $MDSCOUNT); do
18848                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18849                 $LFS setdirstripe -c $i $DIR/$tdir ||
18850                         error "split -c $i $tdir failed"
18851                 wait_update $HOSTNAME \
18852                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18853                         error "dir split not finished"
18854                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18855                         awk '/migrate/ {sum += $2} END { print sum }')
18856                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
18857                 # delta is around total_files/stripe_count
18858                 (( $delta < 200 / (i - 1) + 4 )) ||
18859                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
18860         done
18861 }
18862 run_test 230o "dir split"
18863
18864 test_230p() {
18865         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18866         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18867                 skip "Need MDS version at least 2.13.52"
18868
18869         local mdts=$(comma_list $(mdts_nodes))
18870         local timeout=100
18871         local restripe_status
18872         local delta
18873         local i
18874
18875         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18876
18877         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18878
18879         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18880                            mdt.*MDT0000.enable_dir_restripe)
18881         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18882         stack_trap "do_nodes $mdts $LCTL set_param \
18883                     mdt.*.enable_dir_restripe=$restripe_status"
18884
18885         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18886         createmany -m $DIR/$tdir/f 100 ||
18887                 error "create files under remote dir failed $i"
18888         createmany -d $DIR/$tdir/d 100 ||
18889                 error "create dirs under remote dir failed $i"
18890
18891         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18892                 local mdt_hash="crush"
18893
18894                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18895                 $LFS setdirstripe -c $i $DIR/$tdir ||
18896                         error "split -c $i $tdir failed"
18897                 [ $i -eq 1 ] && mdt_hash="none"
18898                 wait_update $HOSTNAME \
18899                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18900                         error "dir merge not finished"
18901                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18902                         awk '/migrate/ {sum += $2} END { print sum }')
18903                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
18904                 # delta is around total_files/stripe_count
18905                 (( $delta < 200 / i + 4 )) ||
18906                         error "$delta files migrated >= $((200 / i + 4))"
18907         done
18908 }
18909 run_test 230p "dir merge"
18910
18911 test_230q() {
18912         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18913         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18914                 skip "Need MDS version at least 2.13.52"
18915
18916         local mdts=$(comma_list $(mdts_nodes))
18917         local saved_threshold=$(do_facet mds1 \
18918                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18919         local saved_delta=$(do_facet mds1 \
18920                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18921         local threshold=100
18922         local delta=2
18923         local total=0
18924         local stripe_count=0
18925         local stripe_index
18926         local nr_files
18927         local create
18928
18929         # test with fewer files on ZFS
18930         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18931
18932         stack_trap "do_nodes $mdts $LCTL set_param \
18933                     mdt.*.dir_split_count=$saved_threshold"
18934         stack_trap "do_nodes $mdts $LCTL set_param \
18935                     mdt.*.dir_split_delta=$saved_delta"
18936         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18937         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18938         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18939         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18940         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18941         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18942
18943         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18944         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18945
18946         create=$((threshold * 3 / 2))
18947         while [ $stripe_count -lt $MDSCOUNT ]; do
18948                 createmany -m $DIR/$tdir/f $total $create ||
18949                         error "create sub files failed"
18950                 stat $DIR/$tdir > /dev/null
18951                 total=$((total + create))
18952                 stripe_count=$((stripe_count + delta))
18953                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18954
18955                 wait_update $HOSTNAME \
18956                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18957                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18958
18959                 wait_update $HOSTNAME \
18960                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18961                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18962
18963                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
18964                 echo "$nr_files/$total files on MDT$stripe_index after split"
18965                 # allow 10% margin of imbalance with crush hash
18966                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
18967                         error "$nr_files files on MDT$stripe_index after split"
18968
18969                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
18970                 [ $nr_files -eq $total ] ||
18971                         error "total sub files $nr_files != $total"
18972         done
18973 }
18974 run_test 230q "dir auto split"
18975
18976 test_230r() {
18977         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18978         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18979         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18980                 skip "Need MDS version at least 2.13.54"
18981
18982         # maximum amount of local locks:
18983         # parent striped dir - 2 locks
18984         # new stripe in parent to migrate to - 1 lock
18985         # source and target - 2 locks
18986         # Total 5 locks for regular file
18987         mkdir -p $DIR/$tdir
18988         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18989         touch $DIR/$tdir/dir1/eee
18990
18991         # create 4 hardlink for 4 more locks
18992         # Total: 9 locks > RS_MAX_LOCKS (8)
18993         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18994         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18995         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18996         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18997         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18998         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18999         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19000         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19001
19002         cancel_lru_locks mdc
19003
19004         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19005                 error "migrate dir fails"
19006
19007         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19008 }
19009 run_test 230r "migrate with too many local locks"
19010
19011 test_231a()
19012 {
19013         # For simplicity this test assumes that max_pages_per_rpc
19014         # is the same across all OSCs
19015         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19016         local bulk_size=$((max_pages * PAGE_SIZE))
19017         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19018                                        head -n 1)
19019
19020         mkdir -p $DIR/$tdir
19021         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19022                 error "failed to set stripe with -S ${brw_size}M option"
19023
19024         # clear the OSC stats
19025         $LCTL set_param osc.*.stats=0 &>/dev/null
19026         stop_writeback
19027
19028         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19029         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19030                 oflag=direct &>/dev/null || error "dd failed"
19031
19032         sync; sleep 1; sync # just to be safe
19033         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19034         if [ x$nrpcs != "x1" ]; then
19035                 $LCTL get_param osc.*.stats
19036                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19037         fi
19038
19039         start_writeback
19040         # Drop the OSC cache, otherwise we will read from it
19041         cancel_lru_locks osc
19042
19043         # clear the OSC stats
19044         $LCTL set_param osc.*.stats=0 &>/dev/null
19045
19046         # Client reads $bulk_size.
19047         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19048                 iflag=direct &>/dev/null || error "dd failed"
19049
19050         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19051         if [ x$nrpcs != "x1" ]; then
19052                 $LCTL get_param osc.*.stats
19053                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19054         fi
19055 }
19056 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19057
19058 test_231b() {
19059         mkdir -p $DIR/$tdir
19060         local i
19061         for i in {0..1023}; do
19062                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19063                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19064                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19065         done
19066         sync
19067 }
19068 run_test 231b "must not assert on fully utilized OST request buffer"
19069
19070 test_232a() {
19071         mkdir -p $DIR/$tdir
19072         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19073
19074         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19075         do_facet ost1 $LCTL set_param fail_loc=0x31c
19076
19077         # ignore dd failure
19078         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19079
19080         do_facet ost1 $LCTL set_param fail_loc=0
19081         umount_client $MOUNT || error "umount failed"
19082         mount_client $MOUNT || error "mount failed"
19083         stop ost1 || error "cannot stop ost1"
19084         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19085 }
19086 run_test 232a "failed lock should not block umount"
19087
19088 test_232b() {
19089         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19090                 skip "Need MDS version at least 2.10.58"
19091
19092         mkdir -p $DIR/$tdir
19093         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19094         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19095         sync
19096         cancel_lru_locks osc
19097
19098         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19099         do_facet ost1 $LCTL set_param fail_loc=0x31c
19100
19101         # ignore failure
19102         $LFS data_version $DIR/$tdir/$tfile || true
19103
19104         do_facet ost1 $LCTL set_param fail_loc=0
19105         umount_client $MOUNT || error "umount failed"
19106         mount_client $MOUNT || error "mount failed"
19107         stop ost1 || error "cannot stop ost1"
19108         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19109 }
19110 run_test 232b "failed data version lock should not block umount"
19111
19112 test_233a() {
19113         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19114                 skip "Need MDS version at least 2.3.64"
19115         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19116
19117         local fid=$($LFS path2fid $MOUNT)
19118
19119         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19120                 error "cannot access $MOUNT using its FID '$fid'"
19121 }
19122 run_test 233a "checking that OBF of the FS root succeeds"
19123
19124 test_233b() {
19125         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19126                 skip "Need MDS version at least 2.5.90"
19127         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19128
19129         local fid=$($LFS path2fid $MOUNT/.lustre)
19130
19131         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19132                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19133
19134         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19135         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19136                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19137 }
19138 run_test 233b "checking that OBF of the FS .lustre succeeds"
19139
19140 test_234() {
19141         local p="$TMP/sanityN-$TESTNAME.parameters"
19142         save_lustre_params client "llite.*.xattr_cache" > $p
19143         lctl set_param llite.*.xattr_cache 1 ||
19144                 skip_env "xattr cache is not supported"
19145
19146         mkdir -p $DIR/$tdir || error "mkdir failed"
19147         touch $DIR/$tdir/$tfile || error "touch failed"
19148         # OBD_FAIL_LLITE_XATTR_ENOMEM
19149         $LCTL set_param fail_loc=0x1405
19150         getfattr -n user.attr $DIR/$tdir/$tfile &&
19151                 error "getfattr should have failed with ENOMEM"
19152         $LCTL set_param fail_loc=0x0
19153         rm -rf $DIR/$tdir
19154
19155         restore_lustre_params < $p
19156         rm -f $p
19157 }
19158 run_test 234 "xattr cache should not crash on ENOMEM"
19159
19160 test_235() {
19161         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19162                 skip "Need MDS version at least 2.4.52"
19163
19164         flock_deadlock $DIR/$tfile
19165         local RC=$?
19166         case $RC in
19167                 0)
19168                 ;;
19169                 124) error "process hangs on a deadlock"
19170                 ;;
19171                 *) error "error executing flock_deadlock $DIR/$tfile"
19172                 ;;
19173         esac
19174 }
19175 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19176
19177 #LU-2935
19178 test_236() {
19179         check_swap_layouts_support
19180
19181         local ref1=/etc/passwd
19182         local ref2=/etc/group
19183         local file1=$DIR/$tdir/f1
19184         local file2=$DIR/$tdir/f2
19185
19186         test_mkdir -c1 $DIR/$tdir
19187         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19188         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19189         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19190         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19191         local fd=$(free_fd)
19192         local cmd="exec $fd<>$file2"
19193         eval $cmd
19194         rm $file2
19195         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19196                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19197         cmd="exec $fd>&-"
19198         eval $cmd
19199         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19200
19201         #cleanup
19202         rm -rf $DIR/$tdir
19203 }
19204 run_test 236 "Layout swap on open unlinked file"
19205
19206 # LU-4659 linkea consistency
19207 test_238() {
19208         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19209                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19210                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19211                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19212
19213         touch $DIR/$tfile
19214         ln $DIR/$tfile $DIR/$tfile.lnk
19215         touch $DIR/$tfile.new
19216         mv $DIR/$tfile.new $DIR/$tfile
19217         local fid1=$($LFS path2fid $DIR/$tfile)
19218         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19219         local path1=$($LFS fid2path $FSNAME "$fid1")
19220         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19221         local path2=$($LFS fid2path $FSNAME "$fid2")
19222         [ $tfile.lnk == $path2 ] ||
19223                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19224         rm -f $DIR/$tfile*
19225 }
19226 run_test 238 "Verify linkea consistency"
19227
19228 test_239A() { # was test_239
19229         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19230                 skip "Need MDS version at least 2.5.60"
19231
19232         local list=$(comma_list $(mdts_nodes))
19233
19234         mkdir -p $DIR/$tdir
19235         createmany -o $DIR/$tdir/f- 5000
19236         unlinkmany $DIR/$tdir/f- 5000
19237         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19238                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19239         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19240                         osp.*MDT*.sync_in_flight" | calc_sum)
19241         [ "$changes" -eq 0 ] || error "$changes not synced"
19242 }
19243 run_test 239A "osp_sync test"
19244
19245 test_239a() { #LU-5297
19246         remote_mds_nodsh && skip "remote MDS with nodsh"
19247
19248         touch $DIR/$tfile
19249         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19250         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19251         chgrp $RUNAS_GID $DIR/$tfile
19252         wait_delete_completed
19253 }
19254 run_test 239a "process invalid osp sync record correctly"
19255
19256 test_239b() { #LU-5297
19257         remote_mds_nodsh && skip "remote MDS with nodsh"
19258
19259         touch $DIR/$tfile1
19260         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19261         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19262         chgrp $RUNAS_GID $DIR/$tfile1
19263         wait_delete_completed
19264         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19265         touch $DIR/$tfile2
19266         chgrp $RUNAS_GID $DIR/$tfile2
19267         wait_delete_completed
19268 }
19269 run_test 239b "process osp sync record with ENOMEM error correctly"
19270
19271 test_240() {
19272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19273         remote_mds_nodsh && skip "remote MDS with nodsh"
19274
19275         mkdir -p $DIR/$tdir
19276
19277         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19278                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19279         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19280                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19281
19282         umount_client $MOUNT || error "umount failed"
19283         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19284         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19285         mount_client $MOUNT || error "failed to mount client"
19286
19287         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19288         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19289 }
19290 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19291
19292 test_241_bio() {
19293         local count=$1
19294         local bsize=$2
19295
19296         for LOOP in $(seq $count); do
19297                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19298                 cancel_lru_locks $OSC || true
19299         done
19300 }
19301
19302 test_241_dio() {
19303         local count=$1
19304         local bsize=$2
19305
19306         for LOOP in $(seq $1); do
19307                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19308                         2>/dev/null
19309         done
19310 }
19311
19312 test_241a() { # was test_241
19313         local bsize=$PAGE_SIZE
19314
19315         (( bsize < 40960 )) && bsize=40960
19316         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19317         ls -la $DIR/$tfile
19318         cancel_lru_locks $OSC
19319         test_241_bio 1000 $bsize &
19320         PID=$!
19321         test_241_dio 1000 $bsize
19322         wait $PID
19323 }
19324 run_test 241a "bio vs dio"
19325
19326 test_241b() {
19327         local bsize=$PAGE_SIZE
19328
19329         (( bsize < 40960 )) && bsize=40960
19330         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19331         ls -la $DIR/$tfile
19332         test_241_dio 1000 $bsize &
19333         PID=$!
19334         test_241_dio 1000 $bsize
19335         wait $PID
19336 }
19337 run_test 241b "dio vs dio"
19338
19339 test_242() {
19340         remote_mds_nodsh && skip "remote MDS with nodsh"
19341
19342         mkdir -p $DIR/$tdir
19343         touch $DIR/$tdir/$tfile
19344
19345         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19346         do_facet mds1 lctl set_param fail_loc=0x105
19347         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19348
19349         do_facet mds1 lctl set_param fail_loc=0
19350         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19351 }
19352 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19353
19354 test_243()
19355 {
19356         test_mkdir $DIR/$tdir
19357         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19358 }
19359 run_test 243 "various group lock tests"
19360
19361 test_244a()
19362 {
19363         test_mkdir $DIR/$tdir
19364         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19365         sendfile_grouplock $DIR/$tdir/$tfile || \
19366                 error "sendfile+grouplock failed"
19367         rm -rf $DIR/$tdir
19368 }
19369 run_test 244a "sendfile with group lock tests"
19370
19371 test_244b()
19372 {
19373         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19374
19375         local threads=50
19376         local size=$((1024*1024))
19377
19378         test_mkdir $DIR/$tdir
19379         for i in $(seq 1 $threads); do
19380                 local file=$DIR/$tdir/file_$((i / 10))
19381                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19382                 local pids[$i]=$!
19383         done
19384         for i in $(seq 1 $threads); do
19385                 wait ${pids[$i]}
19386         done
19387 }
19388 run_test 244b "multi-threaded write with group lock"
19389
19390 test_245() {
19391         local flagname="multi_mod_rpcs"
19392         local connect_data_name="max_mod_rpcs"
19393         local out
19394
19395         # check if multiple modify RPCs flag is set
19396         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19397                 grep "connect_flags:")
19398         echo "$out"
19399
19400         echo "$out" | grep -qw $flagname
19401         if [ $? -ne 0 ]; then
19402                 echo "connect flag $flagname is not set"
19403                 return
19404         fi
19405
19406         # check if multiple modify RPCs data is set
19407         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19408         echo "$out"
19409
19410         echo "$out" | grep -qw $connect_data_name ||
19411                 error "import should have connect data $connect_data_name"
19412 }
19413 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19414
19415 cleanup_247() {
19416         local submount=$1
19417
19418         trap 0
19419         umount_client $submount
19420         rmdir $submount
19421 }
19422
19423 test_247a() {
19424         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19425                 grep -q subtree ||
19426                 skip_env "Fileset feature is not supported"
19427
19428         local submount=${MOUNT}_$tdir
19429
19430         mkdir $MOUNT/$tdir
19431         mkdir -p $submount || error "mkdir $submount failed"
19432         FILESET="$FILESET/$tdir" mount_client $submount ||
19433                 error "mount $submount failed"
19434         trap "cleanup_247 $submount" EXIT
19435         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19436         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19437                 error "read $MOUNT/$tdir/$tfile failed"
19438         cleanup_247 $submount
19439 }
19440 run_test 247a "mount subdir as fileset"
19441
19442 test_247b() {
19443         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19444                 skip_env "Fileset feature is not supported"
19445
19446         local submount=${MOUNT}_$tdir
19447
19448         rm -rf $MOUNT/$tdir
19449         mkdir -p $submount || error "mkdir $submount failed"
19450         SKIP_FILESET=1
19451         FILESET="$FILESET/$tdir" mount_client $submount &&
19452                 error "mount $submount should fail"
19453         rmdir $submount
19454 }
19455 run_test 247b "mount subdir that dose not exist"
19456
19457 test_247c() {
19458         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19459                 skip_env "Fileset feature is not supported"
19460
19461         local submount=${MOUNT}_$tdir
19462
19463         mkdir -p $MOUNT/$tdir/dir1
19464         mkdir -p $submount || error "mkdir $submount failed"
19465         trap "cleanup_247 $submount" EXIT
19466         FILESET="$FILESET/$tdir" mount_client $submount ||
19467                 error "mount $submount failed"
19468         local fid=$($LFS path2fid $MOUNT/)
19469         $LFS fid2path $submount $fid && error "fid2path should fail"
19470         cleanup_247 $submount
19471 }
19472 run_test 247c "running fid2path outside subdirectory root"
19473
19474 test_247d() {
19475         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19476                 skip "Fileset feature is not supported"
19477
19478         local submount=${MOUNT}_$tdir
19479
19480         mkdir -p $MOUNT/$tdir/dir1
19481         mkdir -p $submount || error "mkdir $submount failed"
19482         FILESET="$FILESET/$tdir" mount_client $submount ||
19483                 error "mount $submount failed"
19484         trap "cleanup_247 $submount" EXIT
19485
19486         local td=$submount/dir1
19487         local fid=$($LFS path2fid $td)
19488         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19489
19490         # check that we get the same pathname back
19491         local rootpath
19492         local found
19493         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19494                 echo "$rootpath $fid"
19495                 found=$($LFS fid2path $rootpath "$fid")
19496                 [ -n "found" ] || error "fid2path should succeed"
19497                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19498         done
19499         # check wrong root path format
19500         rootpath=$submount"_wrong"
19501         found=$($LFS fid2path $rootpath "$fid")
19502         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19503
19504         cleanup_247 $submount
19505 }
19506 run_test 247d "running fid2path inside subdirectory root"
19507
19508 # LU-8037
19509 test_247e() {
19510         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19511                 grep -q subtree ||
19512                 skip "Fileset feature is not supported"
19513
19514         local submount=${MOUNT}_$tdir
19515
19516         mkdir $MOUNT/$tdir
19517         mkdir -p $submount || error "mkdir $submount failed"
19518         FILESET="$FILESET/.." mount_client $submount &&
19519                 error "mount $submount should fail"
19520         rmdir $submount
19521 }
19522 run_test 247e "mount .. as fileset"
19523
19524 test_247f() {
19525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19526         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19527                 skip "Need at least version 2.13.52"
19528         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19529                 skip "Need at least version 2.14.50"
19530         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19531                 grep -q subtree ||
19532                 skip "Fileset feature is not supported"
19533
19534         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19535         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19536                 error "mkdir remote failed"
19537         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19538         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19539                 error "mkdir striped failed"
19540         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19541
19542         local submount=${MOUNT}_$tdir
19543
19544         mkdir -p $submount || error "mkdir $submount failed"
19545         stack_trap "rmdir $submount"
19546
19547         local dir
19548         local stat
19549         local fileset=$FILESET
19550         local mdts=$(comma_list $(mdts_nodes))
19551
19552         stat=$(do_facet mds1 $LCTL get_param -n \
19553                 mdt.*MDT0000.enable_remote_subdir_mount)
19554         stack_trap "do_nodes $mdts $LCTL set_param \
19555                 mdt.*.enable_remote_subdir_mount=$stat"
19556
19557         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19558         stack_trap "umount_client $submount"
19559         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19560                 error "mount remote dir $dir should fail"
19561
19562         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19563                 $tdir/striped/. ; do
19564                 FILESET="$fileset/$dir" mount_client $submount ||
19565                         error "mount $dir failed"
19566                 umount_client $submount
19567         done
19568
19569         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19570         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19571                 error "mount $tdir/remote failed"
19572 }
19573 run_test 247f "mount striped or remote directory as fileset"
19574
19575 test_247g() {
19576         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19577         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19578                 skip "Need at least version 2.14.50"
19579
19580         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
19581                 error "mkdir $tdir failed"
19582         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
19583
19584         local submount=${MOUNT}_$tdir
19585
19586         mkdir -p $submount || error "mkdir $submount failed"
19587         stack_trap "rmdir $submount"
19588
19589         FILESET="$fileset/$tdir" mount_client $submount ||
19590                 error "mount $dir failed"
19591         stack_trap "umount $submount"
19592
19593         local mdts=$(comma_list $(mdts_nodes))
19594
19595         local nrpcs
19596
19597         stat $submount > /dev/null
19598         cancel_lru_locks $MDC
19599         stat $submount > /dev/null
19600         stat $submount/$tfile > /dev/null
19601         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
19602         stat $submount/$tfile > /dev/null
19603         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
19604                 awk '/getattr/ {sum += $2} END {print sum}')
19605
19606         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
19607 }
19608 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
19609
19610 test_248a() {
19611         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19612         [ -z "$fast_read_sav" ] && skip "no fast read support"
19613
19614         # create a large file for fast read verification
19615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19616
19617         # make sure the file is created correctly
19618         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19619                 { rm -f $DIR/$tfile; skip "file creation error"; }
19620
19621         echo "Test 1: verify that fast read is 4 times faster on cache read"
19622
19623         # small read with fast read enabled
19624         $LCTL set_param -n llite.*.fast_read=1
19625         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19626                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19627                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19628         # small read with fast read disabled
19629         $LCTL set_param -n llite.*.fast_read=0
19630         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19631                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19632                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19633
19634         # verify that fast read is 4 times faster for cache read
19635         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19636                 error_not_in_vm "fast read was not 4 times faster: " \
19637                            "$t_fast vs $t_slow"
19638
19639         echo "Test 2: verify the performance between big and small read"
19640         $LCTL set_param -n llite.*.fast_read=1
19641
19642         # 1k non-cache read
19643         cancel_lru_locks osc
19644         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19645                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19646                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19647
19648         # 1M non-cache read
19649         cancel_lru_locks osc
19650         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19651                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19652                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19653
19654         # verify that big IO is not 4 times faster than small IO
19655         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19656                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19657
19658         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19659         rm -f $DIR/$tfile
19660 }
19661 run_test 248a "fast read verification"
19662
19663 test_248b() {
19664         # Default short_io_bytes=16384, try both smaller and larger sizes.
19665         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19666         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19667         echo "bs=53248 count=113 normal buffered write"
19668         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19669                 error "dd of initial data file failed"
19670         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19671
19672         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19673         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19674                 error "dd with sync normal writes failed"
19675         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19676
19677         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19678         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19679                 error "dd with sync small writes failed"
19680         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19681
19682         cancel_lru_locks osc
19683
19684         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19685         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19686         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19687         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19688                 iflag=direct || error "dd with O_DIRECT small read failed"
19689         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19690         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19691                 error "compare $TMP/$tfile.1 failed"
19692
19693         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19694         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19695
19696         # just to see what the maximum tunable value is, and test parsing
19697         echo "test invalid parameter 2MB"
19698         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19699                 error "too-large short_io_bytes allowed"
19700         echo "test maximum parameter 512KB"
19701         # if we can set a larger short_io_bytes, run test regardless of version
19702         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19703                 # older clients may not allow setting it this large, that's OK
19704                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19705                         skip "Need at least client version 2.13.50"
19706                 error "medium short_io_bytes failed"
19707         fi
19708         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19709         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19710
19711         echo "test large parameter 64KB"
19712         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19713         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19714
19715         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19716         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19717                 error "dd with sync large writes failed"
19718         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19719
19720         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19721         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19722         num=$((113 * 4096 / PAGE_SIZE))
19723         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19724         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19725                 error "dd with O_DIRECT large writes failed"
19726         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19727                 error "compare $DIR/$tfile.3 failed"
19728
19729         cancel_lru_locks osc
19730
19731         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19732         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19733                 error "dd with O_DIRECT large read failed"
19734         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19735                 error "compare $TMP/$tfile.2 failed"
19736
19737         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19738         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19739                 error "dd with O_DIRECT large read failed"
19740         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19741                 error "compare $TMP/$tfile.3 failed"
19742 }
19743 run_test 248b "test short_io read and write for both small and large sizes"
19744
19745 test_249() { # LU-7890
19746         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19747                 skip "Need at least version 2.8.54"
19748
19749         rm -f $DIR/$tfile
19750         $LFS setstripe -c 1 $DIR/$tfile
19751         # Offset 2T == 4k * 512M
19752         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19753                 error "dd to 2T offset failed"
19754 }
19755 run_test 249 "Write above 2T file size"
19756
19757 test_250() {
19758         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19759          && skip "no 16TB file size limit on ZFS"
19760
19761         $LFS setstripe -c 1 $DIR/$tfile
19762         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19763         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19764         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19765         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19766                 conv=notrunc,fsync && error "append succeeded"
19767         return 0
19768 }
19769 run_test 250 "Write above 16T limit"
19770
19771 test_251() {
19772         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19773
19774         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19775         #Skip once - writing the first stripe will succeed
19776         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19777         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19778                 error "short write happened"
19779
19780         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19781         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19782                 error "short read happened"
19783
19784         rm -f $DIR/$tfile
19785 }
19786 run_test 251 "Handling short read and write correctly"
19787
19788 test_252() {
19789         remote_mds_nodsh && skip "remote MDS with nodsh"
19790         remote_ost_nodsh && skip "remote OST with nodsh"
19791         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19792                 skip_env "ldiskfs only test"
19793         fi
19794
19795         local tgt
19796         local dev
19797         local out
19798         local uuid
19799         local num
19800         local gen
19801
19802         # check lr_reader on OST0000
19803         tgt=ost1
19804         dev=$(facet_device $tgt)
19805         out=$(do_facet $tgt $LR_READER $dev)
19806         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19807         echo "$out"
19808         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19809         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19810                 error "Invalid uuid returned by $LR_READER on target $tgt"
19811         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19812
19813         # check lr_reader -c on MDT0000
19814         tgt=mds1
19815         dev=$(facet_device $tgt)
19816         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19817                 skip "$LR_READER does not support additional options"
19818         fi
19819         out=$(do_facet $tgt $LR_READER -c $dev)
19820         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19821         echo "$out"
19822         num=$(echo "$out" | grep -c "mdtlov")
19823         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19824                 error "Invalid number of mdtlov clients returned by $LR_READER"
19825         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19826
19827         # check lr_reader -cr on MDT0000
19828         out=$(do_facet $tgt $LR_READER -cr $dev)
19829         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19830         echo "$out"
19831         echo "$out" | grep -q "^reply_data:$" ||
19832                 error "$LR_READER should have returned 'reply_data' section"
19833         num=$(echo "$out" | grep -c "client_generation")
19834         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19835 }
19836 run_test 252 "check lr_reader tool"
19837
19838 test_253() {
19839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19840         remote_mds_nodsh && skip "remote MDS with nodsh"
19841         remote_mgs_nodsh && skip "remote MGS with nodsh"
19842
19843         local ostidx=0
19844         local rc=0
19845         local ost_name=$(ostname_from_index $ostidx)
19846
19847         # on the mdt's osc
19848         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19849         do_facet $SINGLEMDS $LCTL get_param -n \
19850                 osp.$mdtosc_proc1.reserved_mb_high ||
19851                 skip  "remote MDS does not support reserved_mb_high"
19852
19853         rm -rf $DIR/$tdir
19854         wait_mds_ost_sync
19855         wait_delete_completed
19856         mkdir $DIR/$tdir
19857
19858         pool_add $TESTNAME || error "Pool creation failed"
19859         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19860
19861         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19862                 error "Setstripe failed"
19863
19864         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19865
19866         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19867                     grep "watermarks")
19868         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19869
19870         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19871                         osp.$mdtosc_proc1.prealloc_status)
19872         echo "prealloc_status $oa_status"
19873
19874         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19875                 error "File creation should fail"
19876
19877         #object allocation was stopped, but we still able to append files
19878         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19879                 oflag=append || error "Append failed"
19880
19881         rm -f $DIR/$tdir/$tfile.0
19882
19883         # For this test, we want to delete the files we created to go out of
19884         # space but leave the watermark, so we remain nearly out of space
19885         ost_watermarks_enospc_delete_files $tfile $ostidx
19886
19887         wait_delete_completed
19888
19889         sleep_maxage
19890
19891         for i in $(seq 10 12); do
19892                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19893                         2>/dev/null || error "File creation failed after rm"
19894         done
19895
19896         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19897                         osp.$mdtosc_proc1.prealloc_status)
19898         echo "prealloc_status $oa_status"
19899
19900         if (( oa_status != 0 )); then
19901                 error "Object allocation still disable after rm"
19902         fi
19903 }
19904 run_test 253 "Check object allocation limit"
19905
19906 test_254() {
19907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19908         remote_mds_nodsh && skip "remote MDS with nodsh"
19909         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19910                 skip "MDS does not support changelog_size"
19911
19912         local cl_user
19913         local MDT0=$(facet_svc $SINGLEMDS)
19914
19915         changelog_register || error "changelog_register failed"
19916
19917         changelog_clear 0 || error "changelog_clear failed"
19918
19919         local size1=$(do_facet $SINGLEMDS \
19920                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19921         echo "Changelog size $size1"
19922
19923         rm -rf $DIR/$tdir
19924         $LFS mkdir -i 0 $DIR/$tdir
19925         # change something
19926         mkdir -p $DIR/$tdir/pics/2008/zachy
19927         touch $DIR/$tdir/pics/2008/zachy/timestamp
19928         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19929         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19930         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19931         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19932         rm $DIR/$tdir/pics/desktop.jpg
19933
19934         local size2=$(do_facet $SINGLEMDS \
19935                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19936         echo "Changelog size after work $size2"
19937
19938         (( $size2 > $size1 )) ||
19939                 error "new Changelog size=$size2 less than old size=$size1"
19940 }
19941 run_test 254 "Check changelog size"
19942
19943 ladvise_no_type()
19944 {
19945         local type=$1
19946         local file=$2
19947
19948         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19949                 awk -F: '{print $2}' | grep $type > /dev/null
19950         if [ $? -ne 0 ]; then
19951                 return 0
19952         fi
19953         return 1
19954 }
19955
19956 ladvise_no_ioctl()
19957 {
19958         local file=$1
19959
19960         lfs ladvise -a willread $file > /dev/null 2>&1
19961         if [ $? -eq 0 ]; then
19962                 return 1
19963         fi
19964
19965         lfs ladvise -a willread $file 2>&1 |
19966                 grep "Inappropriate ioctl for device" > /dev/null
19967         if [ $? -eq 0 ]; then
19968                 return 0
19969         fi
19970         return 1
19971 }
19972
19973 percent() {
19974         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19975 }
19976
19977 # run a random read IO workload
19978 # usage: random_read_iops <filename> <filesize> <iosize>
19979 random_read_iops() {
19980         local file=$1
19981         local fsize=$2
19982         local iosize=${3:-4096}
19983
19984         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19985                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19986 }
19987
19988 drop_file_oss_cache() {
19989         local file="$1"
19990         local nodes="$2"
19991
19992         $LFS ladvise -a dontneed $file 2>/dev/null ||
19993                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19994 }
19995
19996 ladvise_willread_performance()
19997 {
19998         local repeat=10
19999         local average_origin=0
20000         local average_cache=0
20001         local average_ladvise=0
20002
20003         for ((i = 1; i <= $repeat; i++)); do
20004                 echo "Iter $i/$repeat: reading without willread hint"
20005                 cancel_lru_locks osc
20006                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20007                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20008                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20009                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20010
20011                 cancel_lru_locks osc
20012                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20013                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20014                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20015
20016                 cancel_lru_locks osc
20017                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20018                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20019                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20020                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20021                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20022         done
20023         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20024         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20025         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20026
20027         speedup_cache=$(percent $average_cache $average_origin)
20028         speedup_ladvise=$(percent $average_ladvise $average_origin)
20029
20030         echo "Average uncached read: $average_origin"
20031         echo "Average speedup with OSS cached read: " \
20032                 "$average_cache = +$speedup_cache%"
20033         echo "Average speedup with ladvise willread: " \
20034                 "$average_ladvise = +$speedup_ladvise%"
20035
20036         local lowest_speedup=20
20037         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20038                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20039                         "got $average_cache%. Skipping ladvise willread check."
20040                 return 0
20041         fi
20042
20043         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20044         # it is still good to run until then to exercise 'ladvise willread'
20045         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20046                 [ "$ost1_FSTYPE" = "zfs" ] &&
20047                 echo "osd-zfs does not support dontneed or drop_caches" &&
20048                 return 0
20049
20050         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20051         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20052                 error_not_in_vm "Speedup with willread is less than " \
20053                         "$lowest_speedup%, got $average_ladvise%"
20054 }
20055
20056 test_255a() {
20057         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20058                 skip "lustre < 2.8.54 does not support ladvise "
20059         remote_ost_nodsh && skip "remote OST with nodsh"
20060
20061         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20062
20063         ladvise_no_type willread $DIR/$tfile &&
20064                 skip "willread ladvise is not supported"
20065
20066         ladvise_no_ioctl $DIR/$tfile &&
20067                 skip "ladvise ioctl is not supported"
20068
20069         local size_mb=100
20070         local size=$((size_mb * 1048576))
20071         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20072                 error "dd to $DIR/$tfile failed"
20073
20074         lfs ladvise -a willread $DIR/$tfile ||
20075                 error "Ladvise failed with no range argument"
20076
20077         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20078                 error "Ladvise failed with no -l or -e argument"
20079
20080         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20081                 error "Ladvise failed with only -e argument"
20082
20083         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20084                 error "Ladvise failed with only -l argument"
20085
20086         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20087                 error "End offset should not be smaller than start offset"
20088
20089         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20090                 error "End offset should not be equal to start offset"
20091
20092         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20093                 error "Ladvise failed with overflowing -s argument"
20094
20095         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20096                 error "Ladvise failed with overflowing -e argument"
20097
20098         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20099                 error "Ladvise failed with overflowing -l argument"
20100
20101         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20102                 error "Ladvise succeeded with conflicting -l and -e arguments"
20103
20104         echo "Synchronous ladvise should wait"
20105         local delay=4
20106 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20107         do_nodes $(comma_list $(osts_nodes)) \
20108                 $LCTL set_param fail_val=$delay fail_loc=0x237
20109
20110         local start_ts=$SECONDS
20111         lfs ladvise -a willread $DIR/$tfile ||
20112                 error "Ladvise failed with no range argument"
20113         local end_ts=$SECONDS
20114         local inteval_ts=$((end_ts - start_ts))
20115
20116         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20117                 error "Synchronous advice didn't wait reply"
20118         fi
20119
20120         echo "Asynchronous ladvise shouldn't wait"
20121         local start_ts=$SECONDS
20122         lfs ladvise -a willread -b $DIR/$tfile ||
20123                 error "Ladvise failed with no range argument"
20124         local end_ts=$SECONDS
20125         local inteval_ts=$((end_ts - start_ts))
20126
20127         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20128                 error "Asynchronous advice blocked"
20129         fi
20130
20131         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20132         ladvise_willread_performance
20133 }
20134 run_test 255a "check 'lfs ladvise -a willread'"
20135
20136 facet_meminfo() {
20137         local facet=$1
20138         local info=$2
20139
20140         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20141 }
20142
20143 test_255b() {
20144         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20145                 skip "lustre < 2.8.54 does not support ladvise "
20146         remote_ost_nodsh && skip "remote OST with nodsh"
20147
20148         lfs setstripe -c 1 -i 0 $DIR/$tfile
20149
20150         ladvise_no_type dontneed $DIR/$tfile &&
20151                 skip "dontneed ladvise is not supported"
20152
20153         ladvise_no_ioctl $DIR/$tfile &&
20154                 skip "ladvise ioctl is not supported"
20155
20156         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20157                 [ "$ost1_FSTYPE" = "zfs" ] &&
20158                 skip "zfs-osd does not support 'ladvise dontneed'"
20159
20160         local size_mb=100
20161         local size=$((size_mb * 1048576))
20162         # In order to prevent disturbance of other processes, only check 3/4
20163         # of the memory usage
20164         local kibibytes=$((size_mb * 1024 * 3 / 4))
20165
20166         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20167                 error "dd to $DIR/$tfile failed"
20168
20169         #force write to complete before dropping OST cache & checking memory
20170         sync
20171
20172         local total=$(facet_meminfo ost1 MemTotal)
20173         echo "Total memory: $total KiB"
20174
20175         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20176         local before_read=$(facet_meminfo ost1 Cached)
20177         echo "Cache used before read: $before_read KiB"
20178
20179         lfs ladvise -a willread $DIR/$tfile ||
20180                 error "Ladvise willread failed"
20181         local after_read=$(facet_meminfo ost1 Cached)
20182         echo "Cache used after read: $after_read KiB"
20183
20184         lfs ladvise -a dontneed $DIR/$tfile ||
20185                 error "Ladvise dontneed again failed"
20186         local no_read=$(facet_meminfo ost1 Cached)
20187         echo "Cache used after dontneed ladvise: $no_read KiB"
20188
20189         if [ $total -lt $((before_read + kibibytes)) ]; then
20190                 echo "Memory is too small, abort checking"
20191                 return 0
20192         fi
20193
20194         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20195                 error "Ladvise willread should use more memory" \
20196                         "than $kibibytes KiB"
20197         fi
20198
20199         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20200                 error "Ladvise dontneed should release more memory" \
20201                         "than $kibibytes KiB"
20202         fi
20203 }
20204 run_test 255b "check 'lfs ladvise -a dontneed'"
20205
20206 test_255c() {
20207         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20208                 skip "lustre < 2.10.50 does not support lockahead"
20209
20210         local ost1_imp=$(get_osc_import_name client ost1)
20211         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20212                          cut -d'.' -f2)
20213         local count
20214         local new_count
20215         local difference
20216         local i
20217         local rc
20218
20219         test_mkdir -p $DIR/$tdir
20220         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20221
20222         #test 10 returns only success/failure
20223         i=10
20224         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20225         rc=$?
20226         if [ $rc -eq 255 ]; then
20227                 error "Ladvise test${i} failed, ${rc}"
20228         fi
20229
20230         #test 11 counts lock enqueue requests, all others count new locks
20231         i=11
20232         count=$(do_facet ost1 \
20233                 $LCTL get_param -n ost.OSS.ost.stats)
20234         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20235
20236         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20237         rc=$?
20238         if [ $rc -eq 255 ]; then
20239                 error "Ladvise test${i} failed, ${rc}"
20240         fi
20241
20242         new_count=$(do_facet ost1 \
20243                 $LCTL get_param -n ost.OSS.ost.stats)
20244         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20245                    awk '{ print $2 }')
20246
20247         difference="$((new_count - count))"
20248         if [ $difference -ne $rc ]; then
20249                 error "Ladvise test${i}, bad enqueue count, returned " \
20250                       "${rc}, actual ${difference}"
20251         fi
20252
20253         for i in $(seq 12 21); do
20254                 # If we do not do this, we run the risk of having too many
20255                 # locks and starting lock cancellation while we are checking
20256                 # lock counts.
20257                 cancel_lru_locks osc
20258
20259                 count=$($LCTL get_param -n \
20260                        ldlm.namespaces.$imp_name.lock_unused_count)
20261
20262                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20263                 rc=$?
20264                 if [ $rc -eq 255 ]; then
20265                         error "Ladvise test ${i} failed, ${rc}"
20266                 fi
20267
20268                 new_count=$($LCTL get_param -n \
20269                        ldlm.namespaces.$imp_name.lock_unused_count)
20270                 difference="$((new_count - count))"
20271
20272                 # Test 15 output is divided by 100 to map down to valid return
20273                 if [ $i -eq 15 ]; then
20274                         rc="$((rc * 100))"
20275                 fi
20276
20277                 if [ $difference -ne $rc ]; then
20278                         error "Ladvise test ${i}, bad lock count, returned " \
20279                               "${rc}, actual ${difference}"
20280                 fi
20281         done
20282
20283         #test 22 returns only success/failure
20284         i=22
20285         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20286         rc=$?
20287         if [ $rc -eq 255 ]; then
20288                 error "Ladvise test${i} failed, ${rc}"
20289         fi
20290 }
20291 run_test 255c "suite of ladvise lockahead tests"
20292
20293 test_256() {
20294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20295         remote_mds_nodsh && skip "remote MDS with nodsh"
20296         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20297         changelog_users $SINGLEMDS | grep "^cl" &&
20298                 skip "active changelog user"
20299
20300         local cl_user
20301         local cat_sl
20302         local mdt_dev
20303
20304         mdt_dev=$(mdsdevname 1)
20305         echo $mdt_dev
20306
20307         changelog_register || error "changelog_register failed"
20308
20309         rm -rf $DIR/$tdir
20310         mkdir -p $DIR/$tdir
20311
20312         changelog_clear 0 || error "changelog_clear failed"
20313
20314         # change something
20315         touch $DIR/$tdir/{1..10}
20316
20317         # stop the MDT
20318         stop $SINGLEMDS || error "Fail to stop MDT"
20319
20320         # remount the MDT
20321
20322         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20323
20324         #after mount new plainllog is used
20325         touch $DIR/$tdir/{11..19}
20326         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20327         stack_trap "rm -f $tmpfile"
20328         cat_sl=$(do_facet $SINGLEMDS "sync; \
20329                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20330                  llog_reader $tmpfile | grep -c type=1064553b")
20331         do_facet $SINGLEMDS llog_reader $tmpfile
20332
20333         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20334
20335         changelog_clear 0 || error "changelog_clear failed"
20336
20337         cat_sl=$(do_facet $SINGLEMDS "sync; \
20338                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20339                  llog_reader $tmpfile | grep -c type=1064553b")
20340
20341         if (( cat_sl == 2 )); then
20342                 error "Empty plain llog was not deleted from changelog catalog"
20343         elif (( cat_sl != 1 )); then
20344                 error "Active plain llog shouldn't be deleted from catalog"
20345         fi
20346 }
20347 run_test 256 "Check llog delete for empty and not full state"
20348
20349 test_257() {
20350         remote_mds_nodsh && skip "remote MDS with nodsh"
20351         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20352                 skip "Need MDS version at least 2.8.55"
20353
20354         test_mkdir $DIR/$tdir
20355
20356         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20357                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20358         stat $DIR/$tdir
20359
20360 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20361         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20362         local facet=mds$((mdtidx + 1))
20363         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20364         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20365
20366         stop $facet || error "stop MDS failed"
20367         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20368                 error "start MDS fail"
20369         wait_recovery_complete $facet
20370 }
20371 run_test 257 "xattr locks are not lost"
20372
20373 # Verify we take the i_mutex when security requires it
20374 test_258a() {
20375 #define OBD_FAIL_IMUTEX_SEC 0x141c
20376         $LCTL set_param fail_loc=0x141c
20377         touch $DIR/$tfile
20378         chmod u+s $DIR/$tfile
20379         chmod a+rwx $DIR/$tfile
20380         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20381         RC=$?
20382         if [ $RC -ne 0 ]; then
20383                 error "error, failed to take i_mutex, rc=$?"
20384         fi
20385         rm -f $DIR/$tfile
20386 }
20387 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20388
20389 # Verify we do NOT take the i_mutex in the normal case
20390 test_258b() {
20391 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20392         $LCTL set_param fail_loc=0x141d
20393         touch $DIR/$tfile
20394         chmod a+rwx $DIR
20395         chmod a+rw $DIR/$tfile
20396         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20397         RC=$?
20398         if [ $RC -ne 0 ]; then
20399                 error "error, took i_mutex unnecessarily, rc=$?"
20400         fi
20401         rm -f $DIR/$tfile
20402
20403 }
20404 run_test 258b "verify i_mutex security behavior"
20405
20406 test_259() {
20407         local file=$DIR/$tfile
20408         local before
20409         local after
20410
20411         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20412
20413         stack_trap "rm -f $file" EXIT
20414
20415         wait_delete_completed
20416         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20417         echo "before: $before"
20418
20419         $LFS setstripe -i 0 -c 1 $file
20420         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20421         sync_all_data
20422         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20423         echo "after write: $after"
20424
20425 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20426         do_facet ost1 $LCTL set_param fail_loc=0x2301
20427         $TRUNCATE $file 0
20428         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20429         echo "after truncate: $after"
20430
20431         stop ost1
20432         do_facet ost1 $LCTL set_param fail_loc=0
20433         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20434         sleep 2
20435         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20436         echo "after restart: $after"
20437         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20438                 error "missing truncate?"
20439
20440         return 0
20441 }
20442 run_test 259 "crash at delayed truncate"
20443
20444 test_260() {
20445 #define OBD_FAIL_MDC_CLOSE               0x806
20446         $LCTL set_param fail_loc=0x80000806
20447         touch $DIR/$tfile
20448
20449 }
20450 run_test 260 "Check mdc_close fail"
20451
20452 ### Data-on-MDT sanity tests ###
20453 test_270a() {
20454         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20455                 skip "Need MDS version at least 2.10.55 for DoM"
20456
20457         # create DoM file
20458         local dom=$DIR/$tdir/dom_file
20459         local tmp=$DIR/$tdir/tmp_file
20460
20461         mkdir -p $DIR/$tdir
20462
20463         # basic checks for DoM component creation
20464         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20465                 error "Can set MDT layout to non-first entry"
20466
20467         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20468                 error "Can define multiple entries as MDT layout"
20469
20470         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20471
20472         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20473         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20474         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20475
20476         local mdtidx=$($LFS getstripe -m $dom)
20477         local mdtname=MDT$(printf %04x $mdtidx)
20478         local facet=mds$((mdtidx + 1))
20479         local space_check=1
20480
20481         # Skip free space checks with ZFS
20482         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20483
20484         # write
20485         sync
20486         local size_tmp=$((65536 * 3))
20487         local mdtfree1=$(do_facet $facet \
20488                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20489
20490         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20491         # check also direct IO along write
20492         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20493         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20494         sync
20495         cmp $tmp $dom || error "file data is different"
20496         [ $(stat -c%s $dom) == $size_tmp ] ||
20497                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20498         if [ $space_check == 1 ]; then
20499                 local mdtfree2=$(do_facet $facet \
20500                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20501
20502                 # increase in usage from by $size_tmp
20503                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20504                         error "MDT free space wrong after write: " \
20505                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20506         fi
20507
20508         # truncate
20509         local size_dom=10000
20510
20511         $TRUNCATE $dom $size_dom
20512         [ $(stat -c%s $dom) == $size_dom ] ||
20513                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20514         if [ $space_check == 1 ]; then
20515                 mdtfree1=$(do_facet $facet \
20516                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20517                 # decrease in usage from $size_tmp to new $size_dom
20518                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20519                   $(((size_tmp - size_dom) / 1024)) ] ||
20520                         error "MDT free space is wrong after truncate: " \
20521                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20522         fi
20523
20524         # append
20525         cat $tmp >> $dom
20526         sync
20527         size_dom=$((size_dom + size_tmp))
20528         [ $(stat -c%s $dom) == $size_dom ] ||
20529                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20530         if [ $space_check == 1 ]; then
20531                 mdtfree2=$(do_facet $facet \
20532                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20533                 # increase in usage by $size_tmp from previous
20534                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20535                         error "MDT free space is wrong after append: " \
20536                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20537         fi
20538
20539         # delete
20540         rm $dom
20541         if [ $space_check == 1 ]; then
20542                 mdtfree1=$(do_facet $facet \
20543                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20544                 # decrease in usage by $size_dom from previous
20545                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20546                         error "MDT free space is wrong after removal: " \
20547                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20548         fi
20549
20550         # combined striping
20551         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20552                 error "Can't create DoM + OST striping"
20553
20554         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20555         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20556         # check also direct IO along write
20557         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20558         sync
20559         cmp $tmp $dom || error "file data is different"
20560         [ $(stat -c%s $dom) == $size_tmp ] ||
20561                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20562         rm $dom $tmp
20563
20564         return 0
20565 }
20566 run_test 270a "DoM: basic functionality tests"
20567
20568 test_270b() {
20569         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20570                 skip "Need MDS version at least 2.10.55"
20571
20572         local dom=$DIR/$tdir/dom_file
20573         local max_size=1048576
20574
20575         mkdir -p $DIR/$tdir
20576         $LFS setstripe -E $max_size -L mdt $dom
20577
20578         # truncate over the limit
20579         $TRUNCATE $dom $(($max_size + 1)) &&
20580                 error "successful truncate over the maximum size"
20581         # write over the limit
20582         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20583                 error "successful write over the maximum size"
20584         # append over the limit
20585         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20586         echo "12345" >> $dom && error "successful append over the maximum size"
20587         rm $dom
20588
20589         return 0
20590 }
20591 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20592
20593 test_270c() {
20594         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20595                 skip "Need MDS version at least 2.10.55"
20596
20597         mkdir -p $DIR/$tdir
20598         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20599
20600         # check files inherit DoM EA
20601         touch $DIR/$tdir/first
20602         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20603                 error "bad pattern"
20604         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20605                 error "bad stripe count"
20606         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20607                 error "bad stripe size"
20608
20609         # check directory inherits DoM EA and uses it as default
20610         mkdir $DIR/$tdir/subdir
20611         touch $DIR/$tdir/subdir/second
20612         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20613                 error "bad pattern in sub-directory"
20614         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20615                 error "bad stripe count in sub-directory"
20616         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20617                 error "bad stripe size in sub-directory"
20618         return 0
20619 }
20620 run_test 270c "DoM: DoM EA inheritance tests"
20621
20622 test_270d() {
20623         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20624                 skip "Need MDS version at least 2.10.55"
20625
20626         mkdir -p $DIR/$tdir
20627         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20628
20629         # inherit default DoM striping
20630         mkdir $DIR/$tdir/subdir
20631         touch $DIR/$tdir/subdir/f1
20632
20633         # change default directory striping
20634         $LFS setstripe -c 1 $DIR/$tdir/subdir
20635         touch $DIR/$tdir/subdir/f2
20636         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20637                 error "wrong default striping in file 2"
20638         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20639                 error "bad pattern in file 2"
20640         return 0
20641 }
20642 run_test 270d "DoM: change striping from DoM to RAID0"
20643
20644 test_270e() {
20645         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20646                 skip "Need MDS version at least 2.10.55"
20647
20648         mkdir -p $DIR/$tdir/dom
20649         mkdir -p $DIR/$tdir/norm
20650         DOMFILES=20
20651         NORMFILES=10
20652         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20653         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20654
20655         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20656         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20657
20658         # find DoM files by layout
20659         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20660         [ $NUM -eq  $DOMFILES ] ||
20661                 error "lfs find -L: found $NUM, expected $DOMFILES"
20662         echo "Test 1: lfs find 20 DOM files by layout: OK"
20663
20664         # there should be 1 dir with default DOM striping
20665         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20666         [ $NUM -eq  1 ] ||
20667                 error "lfs find -L: found $NUM, expected 1 dir"
20668         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20669
20670         # find DoM files by stripe size
20671         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20672         [ $NUM -eq  $DOMFILES ] ||
20673                 error "lfs find -S: found $NUM, expected $DOMFILES"
20674         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20675
20676         # find files by stripe offset except DoM files
20677         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20678         [ $NUM -eq  $NORMFILES ] ||
20679                 error "lfs find -i: found $NUM, expected $NORMFILES"
20680         echo "Test 5: lfs find no DOM files by stripe index: OK"
20681         return 0
20682 }
20683 run_test 270e "DoM: lfs find with DoM files test"
20684
20685 test_270f() {
20686         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20687                 skip "Need MDS version at least 2.10.55"
20688
20689         local mdtname=${FSNAME}-MDT0000-mdtlov
20690         local dom=$DIR/$tdir/dom_file
20691         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20692                                                 lod.$mdtname.dom_stripesize)
20693         local dom_limit=131072
20694
20695         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20696         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20697                                                 lod.$mdtname.dom_stripesize)
20698         [ ${dom_limit} -eq ${dom_current} ] ||
20699                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20700
20701         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20702         $LFS setstripe -d $DIR/$tdir
20703         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20704                 error "Can't set directory default striping"
20705
20706         # exceed maximum stripe size
20707         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20708                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20709         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20710                 error "Able to create DoM component size more than LOD limit"
20711
20712         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20713         dom_current=$(do_facet mds1 $LCTL get_param -n \
20714                                                 lod.$mdtname.dom_stripesize)
20715         [ 0 -eq ${dom_current} ] ||
20716                 error "Can't set zero DoM stripe limit"
20717         rm $dom
20718
20719         # attempt to create DoM file on server with disabled DoM should
20720         # remove DoM entry from layout and be succeed
20721         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20722                 error "Can't create DoM file (DoM is disabled)"
20723         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20724                 error "File has DoM component while DoM is disabled"
20725         rm $dom
20726
20727         # attempt to create DoM file with only DoM stripe should return error
20728         $LFS setstripe -E $dom_limit -L mdt $dom &&
20729                 error "Able to create DoM-only file while DoM is disabled"
20730
20731         # too low values to be aligned with smallest stripe size 64K
20732         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20733         dom_current=$(do_facet mds1 $LCTL get_param -n \
20734                                                 lod.$mdtname.dom_stripesize)
20735         [ 30000 -eq ${dom_current} ] &&
20736                 error "Can set too small DoM stripe limit"
20737
20738         # 64K is a minimal stripe size in Lustre, expect limit of that size
20739         [ 65536 -eq ${dom_current} ] ||
20740                 error "Limit is not set to 64K but ${dom_current}"
20741
20742         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20743         dom_current=$(do_facet mds1 $LCTL get_param -n \
20744                                                 lod.$mdtname.dom_stripesize)
20745         echo $dom_current
20746         [ 2147483648 -eq ${dom_current} ] &&
20747                 error "Can set too large DoM stripe limit"
20748
20749         do_facet mds1 $LCTL set_param -n \
20750                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20751         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20752                 error "Can't create DoM component size after limit change"
20753         do_facet mds1 $LCTL set_param -n \
20754                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20755         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20756                 error "Can't create DoM file after limit decrease"
20757         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20758                 error "Can create big DoM component after limit decrease"
20759         touch ${dom}_def ||
20760                 error "Can't create file with old default layout"
20761
20762         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20763         return 0
20764 }
20765 run_test 270f "DoM: maximum DoM stripe size checks"
20766
20767 test_270g() {
20768         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20769                 skip "Need MDS version at least 2.13.52"
20770         local dom=$DIR/$tdir/$tfile
20771
20772         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20773         local lodname=${FSNAME}-MDT0000-mdtlov
20774
20775         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20776         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20777         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20778         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20779
20780         local dom_limit=1024
20781         local dom_threshold="50%"
20782
20783         $LFS setstripe -d $DIR/$tdir
20784         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20785                 error "Can't set directory default striping"
20786
20787         do_facet mds1 $LCTL set_param -n \
20788                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20789         # set 0 threshold and create DOM file to change tunable stripesize
20790         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20791         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20792                 error "Failed to create $dom file"
20793         # now tunable dom_cur_stripesize should reach maximum
20794         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20795                                         lod.${lodname}.dom_stripesize_cur_kb)
20796         [[ $dom_current == $dom_limit ]] ||
20797                 error "Current DOM stripesize is not maximum"
20798         rm $dom
20799
20800         # set threshold for further tests
20801         do_facet mds1 $LCTL set_param -n \
20802                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20803         echo "DOM threshold is $dom_threshold free space"
20804         local dom_def
20805         local dom_set
20806         # Spoof bfree to exceed threshold
20807         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20808         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20809         for spfree in 40 20 0 15 30 55; do
20810                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20811                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20812                         error "Failed to create $dom file"
20813                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20814                                         lod.${lodname}.dom_stripesize_cur_kb)
20815                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20816                 [[ $dom_def != $dom_current ]] ||
20817                         error "Default stripe size was not changed"
20818                 if [[ $spfree > 0 ]] ; then
20819                         dom_set=$($LFS getstripe -S $dom)
20820                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20821                                 error "DOM component size is still old"
20822                 else
20823                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20824                                 error "DoM component is set with no free space"
20825                 fi
20826                 rm $dom
20827                 dom_current=$dom_def
20828         done
20829 }
20830 run_test 270g "DoM: default DoM stripe size depends on free space"
20831
20832 test_270h() {
20833         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20834                 skip "Need MDS version at least 2.13.53"
20835
20836         local mdtname=${FSNAME}-MDT0000-mdtlov
20837         local dom=$DIR/$tdir/$tfile
20838         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20839
20840         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20841         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20842
20843         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20844         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20845                 error "can't create OST file"
20846         # mirrored file with DOM entry in the second mirror
20847         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20848                 error "can't create mirror with DoM component"
20849
20850         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20851
20852         # DOM component in the middle and has other enries in the same mirror,
20853         # should succeed but lost DoM component
20854         $LFS setstripe --copy=${dom}_1 $dom ||
20855                 error "Can't create file from OST|DOM mirror layout"
20856         # check new file has no DoM layout after all
20857         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20858                 error "File has DoM component while DoM is disabled"
20859 }
20860 run_test 270h "DoM: DoM stripe removal when disabled on server"
20861
20862 test_271a() {
20863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20864                 skip "Need MDS version at least 2.10.55"
20865
20866         local dom=$DIR/$tdir/dom
20867
20868         mkdir -p $DIR/$tdir
20869
20870         $LFS setstripe -E 1024K -L mdt $dom
20871
20872         lctl set_param -n mdc.*.stats=clear
20873         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20874         cat $dom > /dev/null
20875         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20876         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20877         ls $dom
20878         rm -f $dom
20879 }
20880 run_test 271a "DoM: data is cached for read after write"
20881
20882 test_271b() {
20883         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20884                 skip "Need MDS version at least 2.10.55"
20885
20886         local dom=$DIR/$tdir/dom
20887
20888         mkdir -p $DIR/$tdir
20889
20890         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20891
20892         lctl set_param -n mdc.*.stats=clear
20893         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20894         cancel_lru_locks mdc
20895         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20896         # second stat to check size is cached on client
20897         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20898         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20899         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20900         rm -f $dom
20901 }
20902 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20903
20904 test_271ba() {
20905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20906                 skip "Need MDS version at least 2.10.55"
20907
20908         local dom=$DIR/$tdir/dom
20909
20910         mkdir -p $DIR/$tdir
20911
20912         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20913
20914         lctl set_param -n mdc.*.stats=clear
20915         lctl set_param -n osc.*.stats=clear
20916         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20917         cancel_lru_locks mdc
20918         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20919         # second stat to check size is cached on client
20920         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20921         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20922         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20923         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20924         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20925         rm -f $dom
20926 }
20927 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20928
20929
20930 get_mdc_stats() {
20931         local mdtidx=$1
20932         local param=$2
20933         local mdt=MDT$(printf %04x $mdtidx)
20934
20935         if [ -z $param ]; then
20936                 lctl get_param -n mdc.*$mdt*.stats
20937         else
20938                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20939         fi
20940 }
20941
20942 test_271c() {
20943         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20944                 skip "Need MDS version at least 2.10.55"
20945
20946         local dom=$DIR/$tdir/dom
20947
20948         mkdir -p $DIR/$tdir
20949
20950         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20951
20952         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20953         local facet=mds$((mdtidx + 1))
20954
20955         cancel_lru_locks mdc
20956         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20957         createmany -o $dom 1000
20958         lctl set_param -n mdc.*.stats=clear
20959         smalliomany -w $dom 1000 200
20960         get_mdc_stats $mdtidx
20961         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20962         # Each file has 1 open, 1 IO enqueues, total 2000
20963         # but now we have also +1 getxattr for security.capability, total 3000
20964         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20965         unlinkmany $dom 1000
20966
20967         cancel_lru_locks mdc
20968         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20969         createmany -o $dom 1000
20970         lctl set_param -n mdc.*.stats=clear
20971         smalliomany -w $dom 1000 200
20972         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20973         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20974         # for OPEN and IO lock.
20975         [ $((enq - enq_2)) -ge 1000 ] ||
20976                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20977         unlinkmany $dom 1000
20978         return 0
20979 }
20980 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20981
20982 cleanup_271def_tests() {
20983         trap 0
20984         rm -f $1
20985 }
20986
20987 test_271d() {
20988         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20989                 skip "Need MDS version at least 2.10.57"
20990
20991         local dom=$DIR/$tdir/dom
20992         local tmp=$TMP/$tfile
20993         trap "cleanup_271def_tests $tmp" EXIT
20994
20995         mkdir -p $DIR/$tdir
20996
20997         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20998
20999         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21000
21001         cancel_lru_locks mdc
21002         dd if=/dev/urandom of=$tmp bs=1000 count=1
21003         dd if=$tmp of=$dom bs=1000 count=1
21004         cancel_lru_locks mdc
21005
21006         cat /etc/hosts >> $tmp
21007         lctl set_param -n mdc.*.stats=clear
21008
21009         # append data to the same file it should update local page
21010         echo "Append to the same page"
21011         cat /etc/hosts >> $dom
21012         local num=$(get_mdc_stats $mdtidx ost_read)
21013         local ra=$(get_mdc_stats $mdtidx req_active)
21014         local rw=$(get_mdc_stats $mdtidx req_waittime)
21015
21016         [ -z $num ] || error "$num READ RPC occured"
21017         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21018         echo "... DONE"
21019
21020         # compare content
21021         cmp $tmp $dom || error "file miscompare"
21022
21023         cancel_lru_locks mdc
21024         lctl set_param -n mdc.*.stats=clear
21025
21026         echo "Open and read file"
21027         cat $dom > /dev/null
21028         local num=$(get_mdc_stats $mdtidx ost_read)
21029         local ra=$(get_mdc_stats $mdtidx req_active)
21030         local rw=$(get_mdc_stats $mdtidx req_waittime)
21031
21032         [ -z $num ] || error "$num READ RPC occured"
21033         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21034         echo "... DONE"
21035
21036         # compare content
21037         cmp $tmp $dom || error "file miscompare"
21038
21039         return 0
21040 }
21041 run_test 271d "DoM: read on open (1K file in reply buffer)"
21042
21043 test_271f() {
21044         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21045                 skip "Need MDS version at least 2.10.57"
21046
21047         local dom=$DIR/$tdir/dom
21048         local tmp=$TMP/$tfile
21049         trap "cleanup_271def_tests $tmp" EXIT
21050
21051         mkdir -p $DIR/$tdir
21052
21053         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21054
21055         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21056
21057         cancel_lru_locks mdc
21058         dd if=/dev/urandom of=$tmp bs=265000 count=1
21059         dd if=$tmp of=$dom bs=265000 count=1
21060         cancel_lru_locks mdc
21061         cat /etc/hosts >> $tmp
21062         lctl set_param -n mdc.*.stats=clear
21063
21064         echo "Append to the same page"
21065         cat /etc/hosts >> $dom
21066         local num=$(get_mdc_stats $mdtidx ost_read)
21067         local ra=$(get_mdc_stats $mdtidx req_active)
21068         local rw=$(get_mdc_stats $mdtidx req_waittime)
21069
21070         [ -z $num ] || error "$num READ RPC occured"
21071         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21072         echo "... DONE"
21073
21074         # compare content
21075         cmp $tmp $dom || error "file miscompare"
21076
21077         cancel_lru_locks mdc
21078         lctl set_param -n mdc.*.stats=clear
21079
21080         echo "Open and read file"
21081         cat $dom > /dev/null
21082         local num=$(get_mdc_stats $mdtidx ost_read)
21083         local ra=$(get_mdc_stats $mdtidx req_active)
21084         local rw=$(get_mdc_stats $mdtidx req_waittime)
21085
21086         [ -z $num ] && num=0
21087         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21088         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21089         echo "... DONE"
21090
21091         # compare content
21092         cmp $tmp $dom || error "file miscompare"
21093
21094         return 0
21095 }
21096 run_test 271f "DoM: read on open (200K file and read tail)"
21097
21098 test_271g() {
21099         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21100                 skip "Skipping due to old client or server version"
21101
21102         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21103         # to get layout
21104         $CHECKSTAT -t file $DIR1/$tfile
21105
21106         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21107         MULTIOP_PID=$!
21108         sleep 1
21109         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21110         $LCTL set_param fail_loc=0x80000314
21111         rm $DIR1/$tfile || error "Unlink fails"
21112         RC=$?
21113         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21114         [ $RC -eq 0 ] || error "Failed write to stale object"
21115 }
21116 run_test 271g "Discard DoM data vs client flush race"
21117
21118 test_272a() {
21119         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21120                 skip "Need MDS version at least 2.11.50"
21121
21122         local dom=$DIR/$tdir/dom
21123         mkdir -p $DIR/$tdir
21124
21125         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21126         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21127                 error "failed to write data into $dom"
21128         local old_md5=$(md5sum $dom)
21129
21130         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21131                 error "failed to migrate to the same DoM component"
21132
21133         local new_md5=$(md5sum $dom)
21134
21135         [ "$old_md5" == "$new_md5" ] ||
21136                 error "md5sum differ: $old_md5, $new_md5"
21137
21138         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21139                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21140 }
21141 run_test 272a "DoM migration: new layout with the same DOM component"
21142
21143 test_272b() {
21144         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21145                 skip "Need MDS version at least 2.11.50"
21146
21147         local dom=$DIR/$tdir/dom
21148         mkdir -p $DIR/$tdir
21149         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21150
21151         local mdtidx=$($LFS getstripe -m $dom)
21152         local mdtname=MDT$(printf %04x $mdtidx)
21153         local facet=mds$((mdtidx + 1))
21154
21155         local mdtfree1=$(do_facet $facet \
21156                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21157         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21158                 error "failed to write data into $dom"
21159         local old_md5=$(md5sum $dom)
21160         cancel_lru_locks mdc
21161         local mdtfree1=$(do_facet $facet \
21162                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21163
21164         $LFS migrate -c2 $dom ||
21165                 error "failed to migrate to the new composite layout"
21166         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21167                 error "MDT stripe was not removed"
21168
21169         cancel_lru_locks mdc
21170         local new_md5=$(md5sum $dom)
21171         [ "$old_md5" == "$new_md5" ] ||
21172                 error "$old_md5 != $new_md5"
21173
21174         # Skip free space checks with ZFS
21175         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21176                 local mdtfree2=$(do_facet $facet \
21177                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21178                 [ $mdtfree2 -gt $mdtfree1 ] ||
21179                         error "MDT space is not freed after migration"
21180         fi
21181         return 0
21182 }
21183 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21184
21185 test_272c() {
21186         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21187                 skip "Need MDS version at least 2.11.50"
21188
21189         local dom=$DIR/$tdir/$tfile
21190         mkdir -p $DIR/$tdir
21191         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21192
21193         local mdtidx=$($LFS getstripe -m $dom)
21194         local mdtname=MDT$(printf %04x $mdtidx)
21195         local facet=mds$((mdtidx + 1))
21196
21197         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21198                 error "failed to write data into $dom"
21199         local old_md5=$(md5sum $dom)
21200         cancel_lru_locks mdc
21201         local mdtfree1=$(do_facet $facet \
21202                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21203
21204         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21205                 error "failed to migrate to the new composite layout"
21206         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21207                 error "MDT stripe was not removed"
21208
21209         cancel_lru_locks mdc
21210         local new_md5=$(md5sum $dom)
21211         [ "$old_md5" == "$new_md5" ] ||
21212                 error "$old_md5 != $new_md5"
21213
21214         # Skip free space checks with ZFS
21215         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21216                 local mdtfree2=$(do_facet $facet \
21217                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21218                 [ $mdtfree2 -gt $mdtfree1 ] ||
21219                         error "MDS space is not freed after migration"
21220         fi
21221         return 0
21222 }
21223 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21224
21225 test_272d() {
21226         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21227                 skip "Need MDS version at least 2.12.55"
21228
21229         local dom=$DIR/$tdir/$tfile
21230         mkdir -p $DIR/$tdir
21231         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21232
21233         local mdtidx=$($LFS getstripe -m $dom)
21234         local mdtname=MDT$(printf %04x $mdtidx)
21235         local facet=mds$((mdtidx + 1))
21236
21237         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21238                 error "failed to write data into $dom"
21239         local old_md5=$(md5sum $dom)
21240         cancel_lru_locks mdc
21241         local mdtfree1=$(do_facet $facet \
21242                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21243
21244         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21245                 error "failed mirroring to the new composite layout"
21246         $LFS mirror resync $dom ||
21247                 error "failed mirror resync"
21248         $LFS mirror split --mirror-id 1 -d $dom ||
21249                 error "failed mirror split"
21250
21251         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21252                 error "MDT stripe was not removed"
21253
21254         cancel_lru_locks mdc
21255         local new_md5=$(md5sum $dom)
21256         [ "$old_md5" == "$new_md5" ] ||
21257                 error "$old_md5 != $new_md5"
21258
21259         # Skip free space checks with ZFS
21260         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21261                 local mdtfree2=$(do_facet $facet \
21262                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21263                 [ $mdtfree2 -gt $mdtfree1 ] ||
21264                         error "MDS space is not freed after DOM mirror deletion"
21265         fi
21266         return 0
21267 }
21268 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21269
21270 test_272e() {
21271         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21272                 skip "Need MDS version at least 2.12.55"
21273
21274         local dom=$DIR/$tdir/$tfile
21275         mkdir -p $DIR/$tdir
21276         $LFS setstripe -c 2 $dom
21277
21278         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21279                 error "failed to write data into $dom"
21280         local old_md5=$(md5sum $dom)
21281         cancel_lru_locks mdc
21282
21283         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21284                 error "failed mirroring to the DOM layout"
21285         $LFS mirror resync $dom ||
21286                 error "failed mirror resync"
21287         $LFS mirror split --mirror-id 1 -d $dom ||
21288                 error "failed mirror split"
21289
21290         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21291                 error "MDT stripe was not removed"
21292
21293         cancel_lru_locks mdc
21294         local new_md5=$(md5sum $dom)
21295         [ "$old_md5" == "$new_md5" ] ||
21296                 error "$old_md5 != $new_md5"
21297
21298         return 0
21299 }
21300 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21301
21302 test_272f() {
21303         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21304                 skip "Need MDS version at least 2.12.55"
21305
21306         local dom=$DIR/$tdir/$tfile
21307         mkdir -p $DIR/$tdir
21308         $LFS setstripe -c 2 $dom
21309
21310         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21311                 error "failed to write data into $dom"
21312         local old_md5=$(md5sum $dom)
21313         cancel_lru_locks mdc
21314
21315         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21316                 error "failed migrating to the DOM file"
21317
21318         cancel_lru_locks mdc
21319         local new_md5=$(md5sum $dom)
21320         [ "$old_md5" != "$new_md5" ] &&
21321                 error "$old_md5 != $new_md5"
21322
21323         return 0
21324 }
21325 run_test 272f "DoM migration: OST-striped file to DOM file"
21326
21327 test_273a() {
21328         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21329                 skip "Need MDS version at least 2.11.50"
21330
21331         # Layout swap cannot be done if either file has DOM component,
21332         # this will never be supported, migration should be used instead
21333
21334         local dom=$DIR/$tdir/$tfile
21335         mkdir -p $DIR/$tdir
21336
21337         $LFS setstripe -c2 ${dom}_plain
21338         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21339         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21340                 error "can swap layout with DoM component"
21341         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21342                 error "can swap layout with DoM component"
21343
21344         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21345         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21346                 error "can swap layout with DoM component"
21347         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21348                 error "can swap layout with DoM component"
21349         return 0
21350 }
21351 run_test 273a "DoM: layout swapping should fail with DOM"
21352
21353 test_273b() {
21354         mkdir -p $DIR/$tdir
21355         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21356
21357 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21358         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21359
21360         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21361 }
21362 run_test 273b "DoM: race writeback and object destroy"
21363
21364 test_275() {
21365         remote_ost_nodsh && skip "remote OST with nodsh"
21366         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21367                 skip "Need OST version >= 2.10.57"
21368
21369         local file=$DIR/$tfile
21370         local oss
21371
21372         oss=$(comma_list $(osts_nodes))
21373
21374         dd if=/dev/urandom of=$file bs=1M count=2 ||
21375                 error "failed to create a file"
21376         cancel_lru_locks osc
21377
21378         #lock 1
21379         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21380                 error "failed to read a file"
21381
21382 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21383         $LCTL set_param fail_loc=0x8000031f
21384
21385         cancel_lru_locks osc &
21386         sleep 1
21387
21388 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21389         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21390         #IO takes another lock, but matches the PENDING one
21391         #and places it to the IO RPC
21392         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21393                 error "failed to read a file with PENDING lock"
21394 }
21395 run_test 275 "Read on a canceled duplicate lock"
21396
21397 test_276() {
21398         remote_ost_nodsh && skip "remote OST with nodsh"
21399         local pid
21400
21401         do_facet ost1 "(while true; do \
21402                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21403                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21404         pid=$!
21405
21406         for LOOP in $(seq 20); do
21407                 stop ost1
21408                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21409         done
21410         kill -9 $pid
21411         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21412                 rm $TMP/sanity_276_pid"
21413 }
21414 run_test 276 "Race between mount and obd_statfs"
21415
21416 test_277() {
21417         $LCTL set_param ldlm.namespaces.*.lru_size=0
21418         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21419         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21420                         grep ^used_mb | awk '{print $2}')
21421         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21423                 oflag=direct conv=notrunc
21424         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21425                         grep ^used_mb | awk '{print $2}')
21426         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21427 }
21428 run_test 277 "Direct IO shall drop page cache"
21429
21430 test_278() {
21431         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21432         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21433         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21434                 skip "needs the same host for mdt1 mdt2" && return
21435
21436         local pid1
21437         local pid2
21438
21439 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21440         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21441         stop mds2 &
21442         pid2=$!
21443
21444         stop mds1
21445
21446         echo "Starting MDTs"
21447         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21448         wait $pid2
21449 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21450 #will return NULL
21451         do_facet mds2 $LCTL set_param fail_loc=0
21452
21453         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21454         wait_recovery_complete mds2
21455 }
21456 run_test 278 "Race starting MDS between MDTs stop/start"
21457
21458 test_280() {
21459         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21460                 skip "Need MGS version at least 2.13.52"
21461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21462         combined_mgs_mds || skip "needs combined MGS/MDT"
21463
21464         umount_client $MOUNT
21465 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21466         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21467
21468         mount_client $MOUNT &
21469         sleep 1
21470         stop mgs || error "stop mgs failed"
21471         #for a race mgs would crash
21472         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21473         mount_client $MOUNT || error "mount client failed"
21474 }
21475 run_test 280 "Race between MGS umount and client llog processing"
21476
21477 cleanup_test_300() {
21478         trap 0
21479         umask $SAVE_UMASK
21480 }
21481 test_striped_dir() {
21482         local mdt_index=$1
21483         local stripe_count
21484         local stripe_index
21485
21486         mkdir -p $DIR/$tdir
21487
21488         SAVE_UMASK=$(umask)
21489         trap cleanup_test_300 RETURN EXIT
21490
21491         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21492                                                 $DIR/$tdir/striped_dir ||
21493                 error "set striped dir error"
21494
21495         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21496         [ "$mode" = "755" ] || error "expect 755 got $mode"
21497
21498         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21499                 error "getdirstripe failed"
21500         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21501         if [ "$stripe_count" != "2" ]; then
21502                 error "1:stripe_count is $stripe_count, expect 2"
21503         fi
21504         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21505         if [ "$stripe_count" != "2" ]; then
21506                 error "2:stripe_count is $stripe_count, expect 2"
21507         fi
21508
21509         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21510         if [ "$stripe_index" != "$mdt_index" ]; then
21511                 error "stripe_index is $stripe_index, expect $mdt_index"
21512         fi
21513
21514         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21515                 error "nlink error after create striped dir"
21516
21517         mkdir $DIR/$tdir/striped_dir/a
21518         mkdir $DIR/$tdir/striped_dir/b
21519
21520         stat $DIR/$tdir/striped_dir/a ||
21521                 error "create dir under striped dir failed"
21522         stat $DIR/$tdir/striped_dir/b ||
21523                 error "create dir under striped dir failed"
21524
21525         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21526                 error "nlink error after mkdir"
21527
21528         rmdir $DIR/$tdir/striped_dir/a
21529         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21530                 error "nlink error after rmdir"
21531
21532         rmdir $DIR/$tdir/striped_dir/b
21533         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21534                 error "nlink error after rmdir"
21535
21536         chattr +i $DIR/$tdir/striped_dir
21537         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21538                 error "immutable flags not working under striped dir!"
21539         chattr -i $DIR/$tdir/striped_dir
21540
21541         rmdir $DIR/$tdir/striped_dir ||
21542                 error "rmdir striped dir error"
21543
21544         cleanup_test_300
21545
21546         true
21547 }
21548
21549 test_300a() {
21550         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21551                 skip "skipped for lustre < 2.7.0"
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21554
21555         test_striped_dir 0 || error "failed on striped dir on MDT0"
21556         test_striped_dir 1 || error "failed on striped dir on MDT0"
21557 }
21558 run_test 300a "basic striped dir sanity test"
21559
21560 test_300b() {
21561         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21562                 skip "skipped for lustre < 2.7.0"
21563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21565
21566         local i
21567         local mtime1
21568         local mtime2
21569         local mtime3
21570
21571         test_mkdir $DIR/$tdir || error "mkdir fail"
21572         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21573                 error "set striped dir error"
21574         for i in {0..9}; do
21575                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21576                 sleep 1
21577                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21578                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21579                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21580                 sleep 1
21581                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21582                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21583                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21584         done
21585         true
21586 }
21587 run_test 300b "check ctime/mtime for striped dir"
21588
21589 test_300c() {
21590         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21591                 skip "skipped for lustre < 2.7.0"
21592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21594
21595         local file_count
21596
21597         mkdir -p $DIR/$tdir
21598         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21599                 error "set striped dir error"
21600
21601         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21602                 error "chown striped dir failed"
21603
21604         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21605                 error "create 5k files failed"
21606
21607         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21608
21609         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21610
21611         rm -rf $DIR/$tdir
21612 }
21613 run_test 300c "chown && check ls under striped directory"
21614
21615 test_300d() {
21616         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21617                 skip "skipped for lustre < 2.7.0"
21618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21620
21621         local stripe_count
21622         local file
21623
21624         mkdir -p $DIR/$tdir
21625         $LFS setstripe -c 2 $DIR/$tdir
21626
21627         #local striped directory
21628         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21629                 error "set striped dir error"
21630         #look at the directories for debug purposes
21631         ls -l $DIR/$tdir
21632         $LFS getdirstripe $DIR/$tdir
21633         ls -l $DIR/$tdir/striped_dir
21634         $LFS getdirstripe $DIR/$tdir/striped_dir
21635         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21636                 error "create 10 files failed"
21637
21638         #remote striped directory
21639         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21640                 error "set striped dir error"
21641         #look at the directories for debug purposes
21642         ls -l $DIR/$tdir
21643         $LFS getdirstripe $DIR/$tdir
21644         ls -l $DIR/$tdir/remote_striped_dir
21645         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21646         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21647                 error "create 10 files failed"
21648
21649         for file in $(find $DIR/$tdir); do
21650                 stripe_count=$($LFS getstripe -c $file)
21651                 [ $stripe_count -eq 2 ] ||
21652                         error "wrong stripe $stripe_count for $file"
21653         done
21654
21655         rm -rf $DIR/$tdir
21656 }
21657 run_test 300d "check default stripe under striped directory"
21658
21659 test_300e() {
21660         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21661                 skip "Need MDS version at least 2.7.55"
21662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21663         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21664
21665         local stripe_count
21666         local file
21667
21668         mkdir -p $DIR/$tdir
21669
21670         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21671                 error "set striped dir error"
21672
21673         touch $DIR/$tdir/striped_dir/a
21674         touch $DIR/$tdir/striped_dir/b
21675         touch $DIR/$tdir/striped_dir/c
21676
21677         mkdir $DIR/$tdir/striped_dir/dir_a
21678         mkdir $DIR/$tdir/striped_dir/dir_b
21679         mkdir $DIR/$tdir/striped_dir/dir_c
21680
21681         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21682                 error "set striped adir under striped dir error"
21683
21684         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21685                 error "set striped bdir under striped dir error"
21686
21687         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21688                 error "set striped cdir under striped dir error"
21689
21690         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21691                 error "rename dir under striped dir fails"
21692
21693         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21694                 error "rename dir under different stripes fails"
21695
21696         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21697                 error "rename file under striped dir should succeed"
21698
21699         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21700                 error "rename dir under striped dir should succeed"
21701
21702         rm -rf $DIR/$tdir
21703 }
21704 run_test 300e "check rename under striped directory"
21705
21706 test_300f() {
21707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21709         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21710                 skip "Need MDS version at least 2.7.55"
21711
21712         local stripe_count
21713         local file
21714
21715         rm -rf $DIR/$tdir
21716         mkdir -p $DIR/$tdir
21717
21718         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21719                 error "set striped dir error"
21720
21721         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21722                 error "set striped dir error"
21723
21724         touch $DIR/$tdir/striped_dir/a
21725         mkdir $DIR/$tdir/striped_dir/dir_a
21726         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21727                 error "create striped dir under striped dir fails"
21728
21729         touch $DIR/$tdir/striped_dir1/b
21730         mkdir $DIR/$tdir/striped_dir1/dir_b
21731         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21732                 error "create striped dir under striped dir fails"
21733
21734         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21735                 error "rename dir under different striped dir should fail"
21736
21737         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21738                 error "rename striped dir under diff striped dir should fail"
21739
21740         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21741                 error "rename file under diff striped dirs fails"
21742
21743         rm -rf $DIR/$tdir
21744 }
21745 run_test 300f "check rename cross striped directory"
21746
21747 test_300_check_default_striped_dir()
21748 {
21749         local dirname=$1
21750         local default_count=$2
21751         local default_index=$3
21752         local stripe_count
21753         local stripe_index
21754         local dir_stripe_index
21755         local dir
21756
21757         echo "checking $dirname $default_count $default_index"
21758         $LFS setdirstripe -D -c $default_count -i $default_index \
21759                                 -t all_char $DIR/$tdir/$dirname ||
21760                 error "set default stripe on striped dir error"
21761         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21762         [ $stripe_count -eq $default_count ] ||
21763                 error "expect $default_count get $stripe_count for $dirname"
21764
21765         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21766         [ $stripe_index -eq $default_index ] ||
21767                 error "expect $default_index get $stripe_index for $dirname"
21768
21769         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21770                                                 error "create dirs failed"
21771
21772         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21773         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21774         for dir in $(find $DIR/$tdir/$dirname/*); do
21775                 stripe_count=$($LFS getdirstripe -c $dir)
21776                 [ $stripe_count -eq $default_count ] ||
21777                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21778                 error "stripe count $default_count != $stripe_count for $dir"
21779
21780                 stripe_index=$($LFS getdirstripe -i $dir)
21781                 [ $default_index -eq -1 ] ||
21782                         [ $stripe_index -eq $default_index ] ||
21783                         error "$stripe_index != $default_index for $dir"
21784
21785                 #check default stripe
21786                 stripe_count=$($LFS getdirstripe -D -c $dir)
21787                 [ $stripe_count -eq $default_count ] ||
21788                 error "default count $default_count != $stripe_count for $dir"
21789
21790                 stripe_index=$($LFS getdirstripe -D -i $dir)
21791                 [ $stripe_index -eq $default_index ] ||
21792                 error "default index $default_index != $stripe_index for $dir"
21793         done
21794         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21795 }
21796
21797 test_300g() {
21798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21799         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21800                 skip "Need MDS version at least 2.7.55"
21801
21802         local dir
21803         local stripe_count
21804         local stripe_index
21805
21806         mkdir $DIR/$tdir
21807         mkdir $DIR/$tdir/normal_dir
21808
21809         #Checking when client cache stripe index
21810         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21811         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21812                 error "create striped_dir failed"
21813
21814         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21815                 error "create dir0 fails"
21816         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21817         [ $stripe_index -eq 0 ] ||
21818                 error "dir0 expect index 0 got $stripe_index"
21819
21820         mkdir $DIR/$tdir/striped_dir/dir1 ||
21821                 error "create dir1 fails"
21822         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21823         [ $stripe_index -eq 1 ] ||
21824                 error "dir1 expect index 1 got $stripe_index"
21825
21826         #check default stripe count/stripe index
21827         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21828         test_300_check_default_striped_dir normal_dir 1 0
21829         test_300_check_default_striped_dir normal_dir 2 1
21830         test_300_check_default_striped_dir normal_dir 2 -1
21831
21832         #delete default stripe information
21833         echo "delete default stripeEA"
21834         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21835                 error "set default stripe on striped dir error"
21836
21837         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21838         for dir in $(find $DIR/$tdir/normal_dir/*); do
21839                 stripe_count=$($LFS getdirstripe -c $dir)
21840                 [ $stripe_count -eq 0 ] ||
21841                         error "expect 1 get $stripe_count for $dir"
21842                 stripe_index=$($LFS getdirstripe -i $dir)
21843                 [ $stripe_index -eq 0 ] ||
21844                         error "expect 0 get $stripe_index for $dir"
21845         done
21846 }
21847 run_test 300g "check default striped directory for normal directory"
21848
21849 test_300h() {
21850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21851         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21852                 skip "Need MDS version at least 2.7.55"
21853
21854         local dir
21855         local stripe_count
21856
21857         mkdir $DIR/$tdir
21858         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21859                 error "set striped dir error"
21860
21861         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21862         test_300_check_default_striped_dir striped_dir 1 0
21863         test_300_check_default_striped_dir striped_dir 2 1
21864         test_300_check_default_striped_dir striped_dir 2 -1
21865
21866         #delete default stripe information
21867         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21868                 error "set default stripe on striped dir error"
21869
21870         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21871         for dir in $(find $DIR/$tdir/striped_dir/*); do
21872                 stripe_count=$($LFS getdirstripe -c $dir)
21873                 [ $stripe_count -eq 0 ] ||
21874                         error "expect 1 get $stripe_count for $dir"
21875         done
21876 }
21877 run_test 300h "check default striped directory for striped directory"
21878
21879 test_300i() {
21880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21881         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21882         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21883                 skip "Need MDS version at least 2.7.55"
21884
21885         local stripe_count
21886         local file
21887
21888         mkdir $DIR/$tdir
21889
21890         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21891                 error "set striped dir error"
21892
21893         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21894                 error "create files under striped dir failed"
21895
21896         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21897                 error "set striped hashdir error"
21898
21899         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21900                 error "create dir0 under hash dir failed"
21901         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21902                 error "create dir1 under hash dir failed"
21903
21904         # unfortunately, we need to umount to clear dir layout cache for now
21905         # once we fully implement dir layout, we can drop this
21906         umount_client $MOUNT || error "umount failed"
21907         mount_client $MOUNT || error "mount failed"
21908
21909         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21910         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21911         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21912
21913         #set the stripe to be unknown hash type
21914         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21915         $LCTL set_param fail_loc=0x1901
21916         for ((i = 0; i < 10; i++)); do
21917                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21918                         error "stat f-$i failed"
21919                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21920         done
21921
21922         touch $DIR/$tdir/striped_dir/f0 &&
21923                 error "create under striped dir with unknown hash should fail"
21924
21925         $LCTL set_param fail_loc=0
21926
21927         umount_client $MOUNT || error "umount failed"
21928         mount_client $MOUNT || error "mount failed"
21929
21930         return 0
21931 }
21932 run_test 300i "client handle unknown hash type striped directory"
21933
21934 test_300j() {
21935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21937         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21938                 skip "Need MDS version at least 2.7.55"
21939
21940         local stripe_count
21941         local file
21942
21943         mkdir $DIR/$tdir
21944
21945         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21946         $LCTL set_param fail_loc=0x1702
21947         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21948                 error "set striped dir error"
21949
21950         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21951                 error "create files under striped dir failed"
21952
21953         $LCTL set_param fail_loc=0
21954
21955         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21956
21957         return 0
21958 }
21959 run_test 300j "test large update record"
21960
21961 test_300k() {
21962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21964         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21965                 skip "Need MDS version at least 2.7.55"
21966
21967         # this test needs a huge transaction
21968         local kb
21969         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21970              osd*.$FSNAME-MDT0000.kbytestotal")
21971         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21972
21973         local stripe_count
21974         local file
21975
21976         mkdir $DIR/$tdir
21977
21978         #define OBD_FAIL_LARGE_STRIPE   0x1703
21979         $LCTL set_param fail_loc=0x1703
21980         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21981                 error "set striped dir error"
21982         $LCTL set_param fail_loc=0
21983
21984         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21985                 error "getstripeddir fails"
21986         rm -rf $DIR/$tdir/striped_dir ||
21987                 error "unlink striped dir fails"
21988
21989         return 0
21990 }
21991 run_test 300k "test large striped directory"
21992
21993 test_300l() {
21994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21996         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21997                 skip "Need MDS version at least 2.7.55"
21998
21999         local stripe_index
22000
22001         test_mkdir -p $DIR/$tdir/striped_dir
22002         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22003                         error "chown $RUNAS_ID failed"
22004         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22005                 error "set default striped dir failed"
22006
22007         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22008         $LCTL set_param fail_loc=0x80000158
22009         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22010
22011         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22012         [ $stripe_index -eq 1 ] ||
22013                 error "expect 1 get $stripe_index for $dir"
22014 }
22015 run_test 300l "non-root user to create dir under striped dir with stale layout"
22016
22017 test_300m() {
22018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22019         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22020         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22021                 skip "Need MDS version at least 2.7.55"
22022
22023         mkdir -p $DIR/$tdir/striped_dir
22024         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22025                 error "set default stripes dir error"
22026
22027         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22028
22029         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22030         [ $stripe_count -eq 0 ] ||
22031                         error "expect 0 get $stripe_count for a"
22032
22033         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22034                 error "set default stripes dir error"
22035
22036         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22037
22038         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22039         [ $stripe_count -eq 0 ] ||
22040                         error "expect 0 get $stripe_count for b"
22041
22042         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22043                 error "set default stripes dir error"
22044
22045         mkdir $DIR/$tdir/striped_dir/c &&
22046                 error "default stripe_index is invalid, mkdir c should fails"
22047
22048         rm -rf $DIR/$tdir || error "rmdir fails"
22049 }
22050 run_test 300m "setstriped directory on single MDT FS"
22051
22052 cleanup_300n() {
22053         local list=$(comma_list $(mdts_nodes))
22054
22055         trap 0
22056         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22057 }
22058
22059 test_300n() {
22060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22062         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22063                 skip "Need MDS version at least 2.7.55"
22064         remote_mds_nodsh && skip "remote MDS with nodsh"
22065
22066         local stripe_index
22067         local list=$(comma_list $(mdts_nodes))
22068
22069         trap cleanup_300n RETURN EXIT
22070         mkdir -p $DIR/$tdir
22071         chmod 777 $DIR/$tdir
22072         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22073                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22074                 error "create striped dir succeeds with gid=0"
22075
22076         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22077         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22078                 error "create striped dir fails with gid=-1"
22079
22080         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22081         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22082                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22083                 error "set default striped dir succeeds with gid=0"
22084
22085
22086         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22087         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22088                 error "set default striped dir fails with gid=-1"
22089
22090
22091         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22092         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22093                                         error "create test_dir fails"
22094         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22095                                         error "create test_dir1 fails"
22096         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22097                                         error "create test_dir2 fails"
22098         cleanup_300n
22099 }
22100 run_test 300n "non-root user to create dir under striped dir with default EA"
22101
22102 test_300o() {
22103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22105         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22106                 skip "Need MDS version at least 2.7.55"
22107
22108         local numfree1
22109         local numfree2
22110
22111         mkdir -p $DIR/$tdir
22112
22113         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22114         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22115         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22116                 skip "not enough free inodes $numfree1 $numfree2"
22117         fi
22118
22119         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22120         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22121         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22122                 skip "not enough free space $numfree1 $numfree2"
22123         fi
22124
22125         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22126                 error "setdirstripe fails"
22127
22128         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22129                 error "create dirs fails"
22130
22131         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22132         ls $DIR/$tdir/striped_dir > /dev/null ||
22133                 error "ls striped dir fails"
22134         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22135                 error "unlink big striped dir fails"
22136 }
22137 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22138
22139 test_300p() {
22140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22142         remote_mds_nodsh && skip "remote MDS with nodsh"
22143
22144         mkdir -p $DIR/$tdir
22145
22146         #define OBD_FAIL_OUT_ENOSPC     0x1704
22147         do_facet mds2 lctl set_param fail_loc=0x80001704
22148         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22149                  && error "create striped directory should fail"
22150
22151         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22152
22153         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22154         true
22155 }
22156 run_test 300p "create striped directory without space"
22157
22158 test_300q() {
22159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22161
22162         local fd=$(free_fd)
22163         local cmd="exec $fd<$tdir"
22164         cd $DIR
22165         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22166         eval $cmd
22167         cmd="exec $fd<&-"
22168         trap "eval $cmd" EXIT
22169         cd $tdir || error "cd $tdir fails"
22170         rmdir  ../$tdir || error "rmdir $tdir fails"
22171         mkdir local_dir && error "create dir succeeds"
22172         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22173         eval $cmd
22174         return 0
22175 }
22176 run_test 300q "create remote directory under orphan directory"
22177
22178 test_300r() {
22179         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22180                 skip "Need MDS version at least 2.7.55" && return
22181         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22182
22183         mkdir $DIR/$tdir
22184
22185         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22186                 error "set striped dir error"
22187
22188         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22189                 error "getstripeddir fails"
22190
22191         local stripe_count
22192         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22193                       awk '/lmv_stripe_count:/ { print $2 }')
22194
22195         [ $MDSCOUNT -ne $stripe_count ] &&
22196                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22197
22198         rm -rf $DIR/$tdir/striped_dir ||
22199                 error "unlink striped dir fails"
22200 }
22201 run_test 300r "test -1 striped directory"
22202
22203 test_300s_helper() {
22204         local count=$1
22205
22206         local stripe_dir=$DIR/$tdir/striped_dir.$count
22207
22208         $LFS mkdir -c $count $stripe_dir ||
22209                 error "lfs mkdir -c error"
22210
22211         $LFS getdirstripe $stripe_dir ||
22212                 error "lfs getdirstripe fails"
22213
22214         local stripe_count
22215         stripe_count=$($LFS getdirstripe $stripe_dir |
22216                       awk '/lmv_stripe_count:/ { print $2 }')
22217
22218         [ $count -ne $stripe_count ] &&
22219                 error_noexit "bad stripe count $stripe_count expected $count"
22220
22221         local dupe_stripes
22222         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22223                 awk '/0x/ {count[$1] += 1}; END {
22224                         for (idx in count) {
22225                                 if (count[idx]>1) {
22226                                         print "index " idx " count " count[idx]
22227                                 }
22228                         }
22229                 }')
22230
22231         if [[ -n "$dupe_stripes" ]] ; then
22232                 lfs getdirstripe $stripe_dir
22233                 error_noexit "Dupe MDT above: $dupe_stripes "
22234         fi
22235
22236         rm -rf $stripe_dir ||
22237                 error_noexit "unlink $stripe_dir fails"
22238 }
22239
22240 test_300s() {
22241         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22242                 skip "Need MDS version at least 2.7.55" && return
22243         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22244
22245         mkdir $DIR/$tdir
22246         for count in $(seq 2 $MDSCOUNT); do
22247                 test_300s_helper $count
22248         done
22249 }
22250 run_test 300s "test lfs mkdir -c without -i"
22251
22252
22253 prepare_remote_file() {
22254         mkdir $DIR/$tdir/src_dir ||
22255                 error "create remote source failed"
22256
22257         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22258                  error "cp to remote source failed"
22259         touch $DIR/$tdir/src_dir/a
22260
22261         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22262                 error "create remote target dir failed"
22263
22264         touch $DIR/$tdir/tgt_dir/b
22265
22266         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22267                 error "rename dir cross MDT failed!"
22268
22269         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22270                 error "src_child still exists after rename"
22271
22272         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22273                 error "missing file(a) after rename"
22274
22275         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22276                 error "diff after rename"
22277 }
22278
22279 test_310a() {
22280         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22282
22283         local remote_file=$DIR/$tdir/tgt_dir/b
22284
22285         mkdir -p $DIR/$tdir
22286
22287         prepare_remote_file || error "prepare remote file failed"
22288
22289         #open-unlink file
22290         $OPENUNLINK $remote_file $remote_file ||
22291                 error "openunlink $remote_file failed"
22292         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22293 }
22294 run_test 310a "open unlink remote file"
22295
22296 test_310b() {
22297         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22299
22300         local remote_file=$DIR/$tdir/tgt_dir/b
22301
22302         mkdir -p $DIR/$tdir
22303
22304         prepare_remote_file || error "prepare remote file failed"
22305
22306         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22307         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22308         $CHECKSTAT -t file $remote_file || error "check file failed"
22309 }
22310 run_test 310b "unlink remote file with multiple links while open"
22311
22312 test_310c() {
22313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22314         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22315
22316         local remote_file=$DIR/$tdir/tgt_dir/b
22317
22318         mkdir -p $DIR/$tdir
22319
22320         prepare_remote_file || error "prepare remote file failed"
22321
22322         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22323         multiop_bg_pause $remote_file O_uc ||
22324                         error "mulitop failed for remote file"
22325         MULTIPID=$!
22326         $MULTIOP $DIR/$tfile Ouc
22327         kill -USR1 $MULTIPID
22328         wait $MULTIPID
22329 }
22330 run_test 310c "open-unlink remote file with multiple links"
22331
22332 #LU-4825
22333 test_311() {
22334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22335         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22336         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22337                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22338         remote_mds_nodsh && skip "remote MDS with nodsh"
22339
22340         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22341         local mdts=$(comma_list $(mdts_nodes))
22342
22343         mkdir -p $DIR/$tdir
22344         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22345         createmany -o $DIR/$tdir/$tfile. 1000
22346
22347         # statfs data is not real time, let's just calculate it
22348         old_iused=$((old_iused + 1000))
22349
22350         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22351                         osp.*OST0000*MDT0000.create_count")
22352         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22353                                 osp.*OST0000*MDT0000.max_create_count")
22354         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22355
22356         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22357         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22358         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22359
22360         unlinkmany $DIR/$tdir/$tfile. 1000
22361
22362         do_nodes $mdts "$LCTL set_param -n \
22363                         osp.*OST0000*.max_create_count=$max_count"
22364         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22365                 do_nodes $mdts "$LCTL set_param -n \
22366                                 osp.*OST0000*.create_count=$count"
22367         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22368                         grep "=0" && error "create_count is zero"
22369
22370         local new_iused
22371         for i in $(seq 120); do
22372                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22373                 # system may be too busy to destroy all objs in time, use
22374                 # a somewhat small value to not fail autotest
22375                 [ $((old_iused - new_iused)) -gt 400 ] && break
22376                 sleep 1
22377         done
22378
22379         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22380         [ $((old_iused - new_iused)) -gt 400 ] ||
22381                 error "objs not destroyed after unlink"
22382 }
22383 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22384
22385 zfs_oid_to_objid()
22386 {
22387         local ost=$1
22388         local objid=$2
22389
22390         local vdevdir=$(dirname $(facet_vdevice $ost))
22391         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22392         local zfs_zapid=$(do_facet $ost $cmd |
22393                           grep -w "/O/0/d$((objid%32))" -C 5 |
22394                           awk '/Object/{getline; print $1}')
22395         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22396                           awk "/$objid = /"'{printf $3}')
22397
22398         echo $zfs_objid
22399 }
22400
22401 zfs_object_blksz() {
22402         local ost=$1
22403         local objid=$2
22404
22405         local vdevdir=$(dirname $(facet_vdevice $ost))
22406         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22407         local blksz=$(do_facet $ost $cmd $objid |
22408                       awk '/dblk/{getline; printf $4}')
22409
22410         case "${blksz: -1}" in
22411                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22412                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22413                 *) ;;
22414         esac
22415
22416         echo $blksz
22417 }
22418
22419 test_312() { # LU-4856
22420         remote_ost_nodsh && skip "remote OST with nodsh"
22421         [ "$ost1_FSTYPE" = "zfs" ] ||
22422                 skip_env "the test only applies to zfs"
22423
22424         local max_blksz=$(do_facet ost1 \
22425                           $ZFS get -p recordsize $(facet_device ost1) |
22426                           awk '!/VALUE/{print $3}')
22427
22428         # to make life a little bit easier
22429         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22430         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22431
22432         local tf=$DIR/$tdir/$tfile
22433         touch $tf
22434         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22435
22436         # Get ZFS object id
22437         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22438         # block size change by sequential overwrite
22439         local bs
22440
22441         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22442                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22443
22444                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22445                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22446         done
22447         rm -f $tf
22448
22449         # block size change by sequential append write
22450         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22451         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22452         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22453         local count
22454
22455         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22456                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22457                         oflag=sync conv=notrunc
22458
22459                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22460                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22461                         error "blksz error, actual $blksz, " \
22462                                 "expected: 2 * $count * $PAGE_SIZE"
22463         done
22464         rm -f $tf
22465
22466         # random write
22467         touch $tf
22468         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22469         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22470
22471         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22472         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22473         [ $blksz -eq $PAGE_SIZE ] ||
22474                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22475
22476         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22477         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22478         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22479
22480         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22481         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22482         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22483 }
22484 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22485
22486 test_313() {
22487         remote_ost_nodsh && skip "remote OST with nodsh"
22488
22489         local file=$DIR/$tfile
22490
22491         rm -f $file
22492         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22493
22494         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22495         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22496         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22497                 error "write should failed"
22498         do_facet ost1 "$LCTL set_param fail_loc=0"
22499         rm -f $file
22500 }
22501 run_test 313 "io should fail after last_rcvd update fail"
22502
22503 test_314() {
22504         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22505
22506         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22507         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22508         rm -f $DIR/$tfile
22509         wait_delete_completed
22510         do_facet ost1 "$LCTL set_param fail_loc=0"
22511 }
22512 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22513
22514 test_315() { # LU-618
22515         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22516
22517         local file=$DIR/$tfile
22518         rm -f $file
22519
22520         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22521                 error "multiop file write failed"
22522         $MULTIOP $file oO_RDONLY:r4063232_c &
22523         PID=$!
22524
22525         sleep 2
22526
22527         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22528         kill -USR1 $PID
22529
22530         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22531         rm -f $file
22532 }
22533 run_test 315 "read should be accounted"
22534
22535 test_316() {
22536         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22537         large_xattr_enabled || skip_env "ea_inode feature disabled"
22538
22539         rm -rf $DIR/$tdir/d
22540         mkdir -p $DIR/$tdir/d
22541         chown nobody $DIR/$tdir/d
22542         touch $DIR/$tdir/d/file
22543
22544         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22545 }
22546 run_test 316 "lfs mv"
22547
22548 test_317() {
22549         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22550                 skip "Need MDS version at least 2.11.53"
22551         if [ "$ost1_FSTYPE" == "zfs" ]; then
22552                 skip "LU-10370: no implementation for ZFS"
22553         fi
22554
22555         local trunc_sz
22556         local grant_blk_size
22557
22558         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22559                         awk '/grant_block_size:/ { print $2; exit; }')
22560         #
22561         # Create File of size 5M. Truncate it to below size's and verify
22562         # blocks count.
22563         #
22564         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22565                 error "Create file $DIR/$tfile failed"
22566         stack_trap "rm -f $DIR/$tfile" EXIT
22567
22568         for trunc_sz in 2097152 4097 4000 509 0; do
22569                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22570                         error "truncate $tfile to $trunc_sz failed"
22571                 local sz=$(stat --format=%s $DIR/$tfile)
22572                 local blk=$(stat --format=%b $DIR/$tfile)
22573                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22574                                      grant_blk_size) * 8))
22575
22576                 if [[ $blk -ne $trunc_blk ]]; then
22577                         $(which stat) $DIR/$tfile
22578                         error "Expected Block $trunc_blk got $blk for $tfile"
22579                 fi
22580
22581                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22582                         error "Expected Size $trunc_sz got $sz for $tfile"
22583         done
22584
22585         #
22586         # sparse file test
22587         # Create file with a hole and write actual two blocks. Block count
22588         # must be 16.
22589         #
22590         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22591                 conv=fsync || error "Create file : $DIR/$tfile"
22592
22593         # Calculate the final truncate size.
22594         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22595
22596         #
22597         # truncate to size $trunc_sz bytes. Strip the last block
22598         # The block count must drop to 8
22599         #
22600         $TRUNCATE $DIR/$tfile $trunc_sz ||
22601                 error "truncate $tfile to $trunc_sz failed"
22602
22603         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22604         sz=$(stat --format=%s $DIR/$tfile)
22605         blk=$(stat --format=%b $DIR/$tfile)
22606
22607         if [[ $blk -ne $trunc_bsz ]]; then
22608                 $(which stat) $DIR/$tfile
22609                 error "Expected Block $trunc_bsz got $blk for $tfile"
22610         fi
22611
22612         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22613                 error "Expected Size $trunc_sz got $sz for $tfile"
22614 }
22615 run_test 317 "Verify blocks get correctly update after truncate"
22616
22617 test_318() {
22618         local old_max_active=$($LCTL get_param -n \
22619                             llite.*.max_read_ahead_async_active 2>/dev/null)
22620
22621         $LCTL set_param llite.*.max_read_ahead_async_active=256
22622         local max_active=$($LCTL get_param -n \
22623                            llite.*.max_read_ahead_async_active 2>/dev/null)
22624         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22625
22626         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22627                 error "set max_read_ahead_async_active should succeed"
22628
22629         $LCTL set_param llite.*.max_read_ahead_async_active=512
22630         max_active=$($LCTL get_param -n \
22631                      llite.*.max_read_ahead_async_active 2>/dev/null)
22632         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22633
22634         # restore @max_active
22635         [ $old_max_active -ne 0 ] && $LCTL set_param \
22636                 llite.*.max_read_ahead_async_active=$old_max_active
22637
22638         local old_threshold=$($LCTL get_param -n \
22639                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22640         local max_per_file_mb=$($LCTL get_param -n \
22641                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22642
22643         local invalid=$(($max_per_file_mb + 1))
22644         $LCTL set_param \
22645                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22646                         && error "set $invalid should fail"
22647
22648         local valid=$(($invalid - 1))
22649         $LCTL set_param \
22650                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22651                         error "set $valid should succeed"
22652         local threshold=$($LCTL get_param -n \
22653                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22654         [ $threshold -eq $valid ] || error \
22655                 "expect threshold $valid got $threshold"
22656         $LCTL set_param \
22657                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22658 }
22659 run_test 318 "Verify async readahead tunables"
22660
22661 test_319() {
22662         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22663
22664         local before=$(date +%s)
22665         local evict
22666         local mdir=$DIR/$tdir
22667         local file=$mdir/xxx
22668
22669         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22670         touch $file
22671
22672 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22673         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22674         $LFS mv -m1 $file &
22675
22676         sleep 1
22677         dd if=$file of=/dev/null
22678         wait
22679         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22680           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22681
22682         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22683 }
22684 run_test 319 "lost lease lock on migrate error"
22685
22686 test_398a() { # LU-4198
22687         local ost1_imp=$(get_osc_import_name client ost1)
22688         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22689                          cut -d'.' -f2)
22690
22691         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22692         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22693
22694         # request a new lock on client
22695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22696
22697         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22698         local lock_count=$($LCTL get_param -n \
22699                            ldlm.namespaces.$imp_name.lru_size)
22700         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22701
22702         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22703
22704         # no lock cached, should use lockless IO and not enqueue new lock
22705         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22706         lock_count=$($LCTL get_param -n \
22707                      ldlm.namespaces.$imp_name.lru_size)
22708         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22709 }
22710 run_test 398a "direct IO should cancel lock otherwise lockless"
22711
22712 test_398b() { # LU-4198
22713         which fio || skip_env "no fio installed"
22714         $LFS setstripe -c -1 $DIR/$tfile
22715
22716         local size=12
22717         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22718
22719         local njobs=4
22720         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22721         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22722                 --numjobs=$njobs --fallocate=none \
22723                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22724                 --filename=$DIR/$tfile &
22725         bg_pid=$!
22726
22727         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22728         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22729                 --numjobs=$njobs --fallocate=none \
22730                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22731                 --filename=$DIR/$tfile || true
22732         wait $bg_pid
22733
22734         rm -rf $DIR/$tfile
22735 }
22736 run_test 398b "DIO and buffer IO race"
22737
22738 test_398c() { # LU-4198
22739         local ost1_imp=$(get_osc_import_name client ost1)
22740         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22741                          cut -d'.' -f2)
22742
22743         which fio || skip_env "no fio installed"
22744
22745         saved_debug=$($LCTL get_param -n debug)
22746         $LCTL set_param debug=0
22747
22748         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22749         ((size /= 1024)) # by megabytes
22750         ((size /= 2)) # write half of the OST at most
22751         [ $size -gt 40 ] && size=40 #reduce test time anyway
22752
22753         $LFS setstripe -c 1 $DIR/$tfile
22754
22755         # it seems like ldiskfs reserves more space than necessary if the
22756         # writing blocks are not mapped, so it extends the file firstly
22757         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22758         cancel_lru_locks osc
22759
22760         # clear and verify rpc_stats later
22761         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22762
22763         local njobs=4
22764         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22765         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22766                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22767                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22768                 --filename=$DIR/$tfile
22769         [ $? -eq 0 ] || error "fio write error"
22770
22771         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22772                 error "Locks were requested while doing AIO"
22773
22774         # get the percentage of 1-page I/O
22775         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22776                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22777                 awk '{print $7}')
22778         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22779
22780         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22781         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22782                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22783                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22784                 --filename=$DIR/$tfile
22785         [ $? -eq 0 ] || error "fio mixed read write error"
22786
22787         echo "AIO with large block size ${size}M"
22788         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22789                 --numjobs=1 --fallocate=none --ioengine=libaio \
22790                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22791                 --filename=$DIR/$tfile
22792         [ $? -eq 0 ] || error "fio large block size failed"
22793
22794         rm -rf $DIR/$tfile
22795         $LCTL set_param debug="$saved_debug"
22796 }
22797 run_test 398c "run fio to test AIO"
22798
22799 test_398d() { #  LU-13846
22800         test -f aiocp || skip_env "no aiocp installed"
22801         local aio_file=$DIR/aio_file
22802
22803         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22804
22805         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22806         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22807
22808         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22809
22810         # make sure we don't crash and fail properly
22811         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22812                 error "aio not aligned with PAGE SIZE should fail"
22813
22814         rm -rf $DIR/$tfile $aio_file
22815 }
22816 run_test 398d "run aiocp to verify block size > stripe size"
22817
22818 test_398e() {
22819         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22820         touch $DIR/$tfile.new
22821         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22822 }
22823 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22824
22825 test_fake_rw() {
22826         local read_write=$1
22827         if [ "$read_write" = "write" ]; then
22828                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22829         elif [ "$read_write" = "read" ]; then
22830                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22831         else
22832                 error "argument error"
22833         fi
22834
22835         # turn off debug for performance testing
22836         local saved_debug=$($LCTL get_param -n debug)
22837         $LCTL set_param debug=0
22838
22839         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22840
22841         # get ost1 size - $FSNAME-OST0000
22842         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22843         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22844         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22845
22846         if [ "$read_write" = "read" ]; then
22847                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22848         fi
22849
22850         local start_time=$(date +%s.%N)
22851         $dd_cmd bs=1M count=$blocks oflag=sync ||
22852                 error "real dd $read_write error"
22853         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22854
22855         if [ "$read_write" = "write" ]; then
22856                 rm -f $DIR/$tfile
22857         fi
22858
22859         # define OBD_FAIL_OST_FAKE_RW           0x238
22860         do_facet ost1 $LCTL set_param fail_loc=0x238
22861
22862         local start_time=$(date +%s.%N)
22863         $dd_cmd bs=1M count=$blocks oflag=sync ||
22864                 error "fake dd $read_write error"
22865         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22866
22867         if [ "$read_write" = "write" ]; then
22868                 # verify file size
22869                 cancel_lru_locks osc
22870                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22871                         error "$tfile size not $blocks MB"
22872         fi
22873         do_facet ost1 $LCTL set_param fail_loc=0
22874
22875         echo "fake $read_write $duration_fake vs. normal $read_write" \
22876                 "$duration in seconds"
22877         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22878                 error_not_in_vm "fake write is slower"
22879
22880         $LCTL set_param -n debug="$saved_debug"
22881         rm -f $DIR/$tfile
22882 }
22883 test_399a() { # LU-7655 for OST fake write
22884         remote_ost_nodsh && skip "remote OST with nodsh"
22885
22886         test_fake_rw write
22887 }
22888 run_test 399a "fake write should not be slower than normal write"
22889
22890 test_399b() { # LU-8726 for OST fake read
22891         remote_ost_nodsh && skip "remote OST with nodsh"
22892         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22893                 skip_env "ldiskfs only test"
22894         fi
22895
22896         test_fake_rw read
22897 }
22898 run_test 399b "fake read should not be slower than normal read"
22899
22900 test_400a() { # LU-1606, was conf-sanity test_74
22901         if ! which $CC > /dev/null 2>&1; then
22902                 skip_env "$CC is not installed"
22903         fi
22904
22905         local extra_flags=''
22906         local out=$TMP/$tfile
22907         local prefix=/usr/include/lustre
22908         local prog
22909
22910         # Oleg removes c files in his test rig so test if any c files exist
22911         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22912                 skip_env "Needed c test files are missing"
22913
22914         if ! [[ -d $prefix ]]; then
22915                 # Assume we're running in tree and fixup the include path.
22916                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22917                 extra_flags+=" -L$LUSTRE/utils/.lib"
22918         fi
22919
22920         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22921                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22922                         error "client api broken"
22923         done
22924         rm -f $out
22925 }
22926 run_test 400a "Lustre client api program can compile and link"
22927
22928 test_400b() { # LU-1606, LU-5011
22929         local header
22930         local out=$TMP/$tfile
22931         local prefix=/usr/include/linux/lustre
22932
22933         # We use a hard coded prefix so that this test will not fail
22934         # when run in tree. There are headers in lustre/include/lustre/
22935         # that are not packaged (like lustre_idl.h) and have more
22936         # complicated include dependencies (like config.h and lnet/types.h).
22937         # Since this test about correct packaging we just skip them when
22938         # they don't exist (see below) rather than try to fixup cppflags.
22939
22940         if ! which $CC > /dev/null 2>&1; then
22941                 skip_env "$CC is not installed"
22942         fi
22943
22944         for header in $prefix/*.h; do
22945                 if ! [[ -f "$header" ]]; then
22946                         continue
22947                 fi
22948
22949                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22950                         continue # lustre_ioctl.h is internal header
22951                 fi
22952
22953                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22954                         error "cannot compile '$header'"
22955         done
22956         rm -f $out
22957 }
22958 run_test 400b "packaged headers can be compiled"
22959
22960 test_401a() { #LU-7437
22961         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22962         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22963
22964         #count the number of parameters by "list_param -R"
22965         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22966         #count the number of parameters by listing proc files
22967         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22968         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22969         echo "proc_dirs='$proc_dirs'"
22970         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22971         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22972                       sort -u | wc -l)
22973
22974         [ $params -eq $procs ] ||
22975                 error "found $params parameters vs. $procs proc files"
22976
22977         # test the list_param -D option only returns directories
22978         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22979         #count the number of parameters by listing proc directories
22980         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22981                 sort -u | wc -l)
22982
22983         [ $params -eq $procs ] ||
22984                 error "found $params parameters vs. $procs proc files"
22985 }
22986 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22987
22988 test_401b() {
22989         # jobid_var may not allow arbitrary values, so use jobid_name
22990         # if available
22991         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22992                 local testname=jobid_name tmp='testing%p'
22993         else
22994                 local testname=jobid_var tmp=testing
22995         fi
22996
22997         local save=$($LCTL get_param -n $testname)
22998
22999         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23000                 error "no error returned when setting bad parameters"
23001
23002         local jobid_new=$($LCTL get_param -n foe $testname baz)
23003         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23004
23005         $LCTL set_param -n fog=bam $testname=$save bat=fog
23006         local jobid_old=$($LCTL get_param -n foe $testname bag)
23007         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23008 }
23009 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23010
23011 test_401c() {
23012         # jobid_var may not allow arbitrary values, so use jobid_name
23013         # if available
23014         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23015                 local testname=jobid_name
23016         else
23017                 local testname=jobid_var
23018         fi
23019
23020         local jobid_var_old=$($LCTL get_param -n $testname)
23021         local jobid_var_new
23022
23023         $LCTL set_param $testname= &&
23024                 error "no error returned for 'set_param a='"
23025
23026         jobid_var_new=$($LCTL get_param -n $testname)
23027         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23028                 error "$testname was changed by setting without value"
23029
23030         $LCTL set_param $testname &&
23031                 error "no error returned for 'set_param a'"
23032
23033         jobid_var_new=$($LCTL get_param -n $testname)
23034         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23035                 error "$testname was changed by setting without value"
23036 }
23037 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23038
23039 test_401d() {
23040         # jobid_var may not allow arbitrary values, so use jobid_name
23041         # if available
23042         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23043                 local testname=jobid_name new_value='foo=bar%p'
23044         else
23045                 local testname=jobid_var new_valuie=foo=bar
23046         fi
23047
23048         local jobid_var_old=$($LCTL get_param -n $testname)
23049         local jobid_var_new
23050
23051         $LCTL set_param $testname=$new_value ||
23052                 error "'set_param a=b' did not accept a value containing '='"
23053
23054         jobid_var_new=$($LCTL get_param -n $testname)
23055         [[ "$jobid_var_new" == "$new_value" ]] ||
23056                 error "'set_param a=b' failed on a value containing '='"
23057
23058         # Reset the $testname to test the other format
23059         $LCTL set_param $testname=$jobid_var_old
23060         jobid_var_new=$($LCTL get_param -n $testname)
23061         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23062                 error "failed to reset $testname"
23063
23064         $LCTL set_param $testname $new_value ||
23065                 error "'set_param a b' did not accept a value containing '='"
23066
23067         jobid_var_new=$($LCTL get_param -n $testname)
23068         [[ "$jobid_var_new" == "$new_value" ]] ||
23069                 error "'set_param a b' failed on a value containing '='"
23070
23071         $LCTL set_param $testname $jobid_var_old
23072         jobid_var_new=$($LCTL get_param -n $testname)
23073         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23074                 error "failed to reset $testname"
23075 }
23076 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23077
23078 test_402() {
23079         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23080         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23081                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23082         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23083                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23084                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23085         remote_mds_nodsh && skip "remote MDS with nodsh"
23086
23087         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23088 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23089         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23090         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23091                 echo "Touch failed - OK"
23092 }
23093 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23094
23095 test_403() {
23096         local file1=$DIR/$tfile.1
23097         local file2=$DIR/$tfile.2
23098         local tfile=$TMP/$tfile
23099
23100         rm -f $file1 $file2 $tfile
23101
23102         touch $file1
23103         ln $file1 $file2
23104
23105         # 30 sec OBD_TIMEOUT in ll_getattr()
23106         # right before populating st_nlink
23107         $LCTL set_param fail_loc=0x80001409
23108         stat -c %h $file1 > $tfile &
23109
23110         # create an alias, drop all locks and reclaim the dentry
23111         < $file2
23112         cancel_lru_locks mdc
23113         cancel_lru_locks osc
23114         sysctl -w vm.drop_caches=2
23115
23116         wait
23117
23118         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23119
23120         rm -f $tfile $file1 $file2
23121 }
23122 run_test 403 "i_nlink should not drop to zero due to aliasing"
23123
23124 test_404() { # LU-6601
23125         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23126                 skip "Need server version newer than 2.8.52"
23127         remote_mds_nodsh && skip "remote MDS with nodsh"
23128
23129         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23130                 awk '/osp .*-osc-MDT/ { print $4}')
23131
23132         local osp
23133         for osp in $mosps; do
23134                 echo "Deactivate: " $osp
23135                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23136                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23137                         awk -vp=$osp '$4 == p { print $2 }')
23138                 [ $stat = IN ] || {
23139                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23140                         error "deactivate error"
23141                 }
23142                 echo "Activate: " $osp
23143                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23144                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23145                         awk -vp=$osp '$4 == p { print $2 }')
23146                 [ $stat = UP ] || {
23147                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23148                         error "activate error"
23149                 }
23150         done
23151 }
23152 run_test 404 "validate manual {de}activated works properly for OSPs"
23153
23154 test_405() {
23155         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23156         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23157                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23158                         skip "Layout swap lock is not supported"
23159
23160         check_swap_layouts_support
23161         check_swap_layout_no_dom $DIR
23162
23163         test_mkdir $DIR/$tdir
23164         swap_lock_test -d $DIR/$tdir ||
23165                 error "One layout swap locked test failed"
23166 }
23167 run_test 405 "Various layout swap lock tests"
23168
23169 test_406() {
23170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23171         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23172         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23174         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23175                 skip "Need MDS version at least 2.8.50"
23176
23177         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23178         local test_pool=$TESTNAME
23179
23180         pool_add $test_pool || error "pool_add failed"
23181         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23182                 error "pool_add_targets failed"
23183
23184         save_layout_restore_at_exit $MOUNT
23185
23186         # parent set default stripe count only, child will stripe from both
23187         # parent and fs default
23188         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23189                 error "setstripe $MOUNT failed"
23190         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23191         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23192         for i in $(seq 10); do
23193                 local f=$DIR/$tdir/$tfile.$i
23194                 touch $f || error "touch failed"
23195                 local count=$($LFS getstripe -c $f)
23196                 [ $count -eq $OSTCOUNT ] ||
23197                         error "$f stripe count $count != $OSTCOUNT"
23198                 local offset=$($LFS getstripe -i $f)
23199                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23200                 local size=$($LFS getstripe -S $f)
23201                 [ $size -eq $((def_stripe_size * 2)) ] ||
23202                         error "$f stripe size $size != $((def_stripe_size * 2))"
23203                 local pool=$($LFS getstripe -p $f)
23204                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23205         done
23206
23207         # change fs default striping, delete parent default striping, now child
23208         # will stripe from new fs default striping only
23209         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23210                 error "change $MOUNT default stripe failed"
23211         $LFS setstripe -c 0 $DIR/$tdir ||
23212                 error "delete $tdir default stripe failed"
23213         for i in $(seq 11 20); do
23214                 local f=$DIR/$tdir/$tfile.$i
23215                 touch $f || error "touch $f failed"
23216                 local count=$($LFS getstripe -c $f)
23217                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23218                 local offset=$($LFS getstripe -i $f)
23219                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23220                 local size=$($LFS getstripe -S $f)
23221                 [ $size -eq $def_stripe_size ] ||
23222                         error "$f stripe size $size != $def_stripe_size"
23223                 local pool=$($LFS getstripe -p $f)
23224                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23225         done
23226
23227         unlinkmany $DIR/$tdir/$tfile. 1 20
23228
23229         local f=$DIR/$tdir/$tfile
23230         pool_remove_all_targets $test_pool $f
23231         pool_remove $test_pool $f
23232 }
23233 run_test 406 "DNE support fs default striping"
23234
23235 test_407() {
23236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23237         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23238                 skip "Need MDS version at least 2.8.55"
23239         remote_mds_nodsh && skip "remote MDS with nodsh"
23240
23241         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23242                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23243         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23244                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23245         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23246
23247         #define OBD_FAIL_DT_TXN_STOP    0x2019
23248         for idx in $(seq $MDSCOUNT); do
23249                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23250         done
23251         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23252         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23253                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23254         true
23255 }
23256 run_test 407 "transaction fail should cause operation fail"
23257
23258 test_408() {
23259         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23260
23261         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23262         lctl set_param fail_loc=0x8000040a
23263         # let ll_prepare_partial_page() fail
23264         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23265
23266         rm -f $DIR/$tfile
23267
23268         # create at least 100 unused inodes so that
23269         # shrink_icache_memory(0) should not return 0
23270         touch $DIR/$tfile-{0..100}
23271         rm -f $DIR/$tfile-{0..100}
23272         sync
23273
23274         echo 2 > /proc/sys/vm/drop_caches
23275 }
23276 run_test 408 "drop_caches should not hang due to page leaks"
23277
23278 test_409()
23279 {
23280         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23281
23282         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23283         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23284         touch $DIR/$tdir/guard || error "(2) Fail to create"
23285
23286         local PREFIX=$(str_repeat 'A' 128)
23287         echo "Create 1K hard links start at $(date)"
23288         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23289                 error "(3) Fail to hard link"
23290
23291         echo "Links count should be right although linkEA overflow"
23292         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23293         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23294         [ $linkcount -eq 1001 ] ||
23295                 error "(5) Unexpected hard links count: $linkcount"
23296
23297         echo "List all links start at $(date)"
23298         ls -l $DIR/$tdir/foo > /dev/null ||
23299                 error "(6) Fail to list $DIR/$tdir/foo"
23300
23301         echo "Unlink hard links start at $(date)"
23302         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23303                 error "(7) Fail to unlink"
23304         echo "Unlink hard links finished at $(date)"
23305 }
23306 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23307
23308 test_410()
23309 {
23310         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23311                 skip "Need client version at least 2.9.59"
23312         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23313                 skip "Need MODULES build"
23314
23315         # Create a file, and stat it from the kernel
23316         local testfile=$DIR/$tfile
23317         touch $testfile
23318
23319         local run_id=$RANDOM
23320         local my_ino=$(stat --format "%i" $testfile)
23321
23322         # Try to insert the module. This will always fail as the
23323         # module is designed to not be inserted.
23324         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23325             &> /dev/null
23326
23327         # Anything but success is a test failure
23328         dmesg | grep -q \
23329             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23330             error "no inode match"
23331 }
23332 run_test 410 "Test inode number returned from kernel thread"
23333
23334 cleanup_test411_cgroup() {
23335         trap 0
23336         rmdir "$1"
23337 }
23338
23339 test_411() {
23340         local cg_basedir=/sys/fs/cgroup/memory
23341         # LU-9966
23342         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23343                 skip "no setup for cgroup"
23344
23345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23346                 error "test file creation failed"
23347         cancel_lru_locks osc
23348
23349         # Create a very small memory cgroup to force a slab allocation error
23350         local cgdir=$cg_basedir/osc_slab_alloc
23351         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23352         trap "cleanup_test411_cgroup $cgdir" EXIT
23353         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23354         echo 1M > $cgdir/memory.limit_in_bytes
23355
23356         # Should not LBUG, just be killed by oom-killer
23357         # dd will return 0 even allocation failure in some environment.
23358         # So don't check return value
23359         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23360         cleanup_test411_cgroup $cgdir
23361
23362         return 0
23363 }
23364 run_test 411 "Slab allocation error with cgroup does not LBUG"
23365
23366 test_412() {
23367         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23368         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23369                 skip "Need server version at least 2.10.55"
23370         fi
23371
23372         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23373                 error "mkdir failed"
23374         $LFS getdirstripe $DIR/$tdir
23375         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23376         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23377                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23378         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23379         [ $stripe_count -eq 2 ] ||
23380                 error "expect 2 get $stripe_count"
23381 }
23382 run_test 412 "mkdir on specific MDTs"
23383
23384 test_qos_mkdir() {
23385         local mkdir_cmd=$1
23386         local stripe_count=$2
23387         local mdts=$(comma_list $(mdts_nodes))
23388
23389         local testdir
23390         local lmv_qos_prio_free
23391         local lmv_qos_threshold_rr
23392         local lmv_qos_maxage
23393         local lod_qos_prio_free
23394         local lod_qos_threshold_rr
23395         local lod_qos_maxage
23396         local count
23397         local i
23398
23399         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23400         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23401         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23402                 head -n1)
23403         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23404         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23405         stack_trap "$LCTL set_param \
23406                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23407         stack_trap "$LCTL set_param \
23408                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23409         stack_trap "$LCTL set_param \
23410                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23411
23412         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23413                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23414         lod_qos_prio_free=${lod_qos_prio_free%%%}
23415         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23416                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23417         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23418         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23419                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23420         stack_trap "do_nodes $mdts $LCTL set_param \
23421                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23422         stack_trap "do_nodes $mdts $LCTL set_param \
23423                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23424                 EXIT
23425         stack_trap "do_nodes $mdts $LCTL set_param \
23426                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23427
23428         echo
23429         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23430
23431         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23432         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23433
23434         testdir=$DIR/$tdir-s$stripe_count/rr
23435
23436         for i in $(seq $((100 * MDSCOUNT))); do
23437                 eval $mkdir_cmd $testdir/subdir$i ||
23438                         error "$mkdir_cmd subdir$i failed"
23439         done
23440
23441         for i in $(seq $MDSCOUNT); do
23442                 count=$($LFS getdirstripe -i $testdir/* |
23443                                 grep ^$((i - 1))$ | wc -l)
23444                 echo "$count directories created on MDT$((i - 1))"
23445                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23446
23447                 if [ $stripe_count -gt 1 ]; then
23448                         count=$($LFS getdirstripe $testdir/* |
23449                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23450                         echo "$count stripes created on MDT$((i - 1))"
23451                         # deviation should < 5% of average
23452                         [ $count -lt $((95 * stripe_count)) ] ||
23453                         [ $count -gt $((105 * stripe_count)) ] &&
23454                                 error "stripes are not evenly distributed"
23455                 fi
23456         done
23457
23458         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23459         do_nodes $mdts $LCTL set_param \
23460                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23461
23462         echo
23463         echo "Check for uneven MDTs: "
23464
23465         local ffree
23466         local bavail
23467         local max
23468         local min
23469         local max_index
23470         local min_index
23471         local tmp
23472
23473         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23474         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23475         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23476
23477         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23478         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23479         max_index=0
23480         min_index=0
23481         for ((i = 1; i < ${#ffree[@]}; i++)); do
23482                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23483                 if [ $tmp -gt $max ]; then
23484                         max=$tmp
23485                         max_index=$i
23486                 fi
23487                 if [ $tmp -lt $min ]; then
23488                         min=$tmp
23489                         min_index=$i
23490                 fi
23491         done
23492
23493         [ ${ffree[min_index]} -eq 0 ] &&
23494                 skip "no free files in MDT$min_index"
23495         [ ${ffree[min_index]} -gt 100000000 ] &&
23496                 skip "too much free files in MDT$min_index"
23497
23498         # Check if we need to generate uneven MDTs
23499         local threshold=50
23500         local diff=$(((max - min) * 100 / min))
23501         local value="$(generate_string 1024)"
23502
23503         while [ $diff -lt $threshold ]; do
23504                 # generate uneven MDTs, create till $threshold% diff
23505                 echo -n "weight diff=$diff% must be > $threshold% ..."
23506                 count=$((${ffree[min_index]} / 10))
23507                 # 50 sec per 10000 files in vm
23508                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23509                         skip "$count files to create"
23510                 echo "Fill MDT$min_index with $count files"
23511                 [ -d $DIR/$tdir-MDT$min_index ] ||
23512                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23513                         error "mkdir $tdir-MDT$min_index failed"
23514                 for i in $(seq $count); do
23515                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23516                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23517                                 error "create f$j_$i failed"
23518                         setfattr -n user.413b -v $value \
23519                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23520                                 error "setfattr f$j_$i failed"
23521                 done
23522
23523                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23524                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23525                 max=$(((${ffree[max_index]} >> 8) * \
23526                         (${bavail[max_index]} * bsize >> 16)))
23527                 min=$(((${ffree[min_index]} >> 8) * \
23528                         (${bavail[min_index]} * bsize >> 16)))
23529                 diff=$(((max - min) * 100 / min))
23530         done
23531
23532         echo "MDT filesfree available: ${ffree[@]}"
23533         echo "MDT blocks available: ${bavail[@]}"
23534         echo "weight diff=$diff%"
23535
23536         echo
23537         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23538
23539         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23540         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23541         # decrease statfs age, so that it can be updated in time
23542         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23543         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23544
23545         sleep 1
23546
23547         testdir=$DIR/$tdir-s$stripe_count/qos
23548
23549         for i in $(seq $((100 * MDSCOUNT))); do
23550                 eval $mkdir_cmd $testdir/subdir$i ||
23551                         error "$mkdir_cmd subdir$i failed"
23552         done
23553
23554         for i in $(seq $MDSCOUNT); do
23555                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23556                         wc -l)
23557                 echo "$count directories created on MDT$((i - 1))"
23558
23559                 if [ $stripe_count -gt 1 ]; then
23560                         count=$($LFS getdirstripe $testdir/* |
23561                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23562                         echo "$count stripes created on MDT$((i - 1))"
23563                 fi
23564         done
23565
23566         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23567         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23568
23569         # D-value should > 10% of averge
23570         [ $((max - min)) -lt 10 ] &&
23571                 error "subdirs shouldn't be evenly distributed"
23572
23573         # ditto
23574         if [ $stripe_count -gt 1 ]; then
23575                 max=$($LFS getdirstripe $testdir/* |
23576                         grep -P "^\s+$max_index\t" | wc -l)
23577                 min=$($LFS getdirstripe $testdir/* |
23578                         grep -P "^\s+$min_index\t" | wc -l)
23579                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23580                         error "stripes shouldn't be evenly distributed"|| true
23581         fi
23582 }
23583
23584 test_413a() {
23585         [ $MDSCOUNT -lt 2 ] &&
23586                 skip "We need at least 2 MDTs for this test"
23587
23588         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23589                 skip "Need server version at least 2.12.52"
23590
23591         local stripe_count
23592
23593         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23594                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23595                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23596                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23597                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23598         done
23599 }
23600 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23601
23602 test_413b() {
23603         [ $MDSCOUNT -lt 2 ] &&
23604                 skip "We need at least 2 MDTs for this test"
23605
23606         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23607                 skip "Need server version at least 2.12.52"
23608
23609         local stripe_count
23610
23611         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23612                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23613                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23614                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23615                 $LFS setdirstripe -D -c $stripe_count \
23616                         $DIR/$tdir-s$stripe_count/rr ||
23617                         error "setdirstripe failed"
23618                 $LFS setdirstripe -D -c $stripe_count \
23619                         $DIR/$tdir-s$stripe_count/qos ||
23620                         error "setdirstripe failed"
23621                 test_qos_mkdir "mkdir" $stripe_count
23622         done
23623 }
23624 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23625
23626 test_414() {
23627 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23628         $LCTL set_param fail_loc=0x80000521
23629         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23630         rm -f $DIR/$tfile
23631 }
23632 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23633
23634 test_415() {
23635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23636         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23637                 skip "Need server version at least 2.11.52"
23638
23639         # LU-11102
23640         local total
23641         local setattr_pid
23642         local start_time
23643         local end_time
23644         local duration
23645
23646         total=500
23647         # this test may be slow on ZFS
23648         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23649
23650         # though this test is designed for striped directory, let's test normal
23651         # directory too since lock is always saved as CoS lock.
23652         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23653         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23654
23655         (
23656                 while true; do
23657                         touch $DIR/$tdir
23658                 done
23659         ) &
23660         setattr_pid=$!
23661
23662         start_time=$(date +%s)
23663         for i in $(seq $total); do
23664                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23665                         > /dev/null
23666         done
23667         end_time=$(date +%s)
23668         duration=$((end_time - start_time))
23669
23670         kill -9 $setattr_pid
23671
23672         echo "rename $total files took $duration sec"
23673         [ $duration -lt 100 ] || error "rename took $duration sec"
23674 }
23675 run_test 415 "lock revoke is not missing"
23676
23677 test_416() {
23678         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23679                 skip "Need server version at least 2.11.55"
23680
23681         # define OBD_FAIL_OSD_TXN_START    0x19a
23682         do_facet mds1 lctl set_param fail_loc=0x19a
23683
23684         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23685
23686         true
23687 }
23688 run_test 416 "transaction start failure won't cause system hung"
23689
23690 cleanup_417() {
23691         trap 0
23692         do_nodes $(comma_list $(mdts_nodes)) \
23693                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23694         do_nodes $(comma_list $(mdts_nodes)) \
23695                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23696         do_nodes $(comma_list $(mdts_nodes)) \
23697                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23698 }
23699
23700 test_417() {
23701         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23702         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23703                 skip "Need MDS version at least 2.11.56"
23704
23705         trap cleanup_417 RETURN EXIT
23706
23707         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23708         do_nodes $(comma_list $(mdts_nodes)) \
23709                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23710         $LFS migrate -m 0 $DIR/$tdir.1 &&
23711                 error "migrate dir $tdir.1 should fail"
23712
23713         do_nodes $(comma_list $(mdts_nodes)) \
23714                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23715         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23716                 error "create remote dir $tdir.2 should fail"
23717
23718         do_nodes $(comma_list $(mdts_nodes)) \
23719                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23720         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23721                 error "create striped dir $tdir.3 should fail"
23722         true
23723 }
23724 run_test 417 "disable remote dir, striped dir and dir migration"
23725
23726 # Checks that the outputs of df [-i] and lfs df [-i] match
23727 #
23728 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23729 check_lfs_df() {
23730         local dir=$2
23731         local inodes
23732         local df_out
23733         local lfs_df_out
23734         local count
23735         local passed=false
23736
23737         # blocks or inodes
23738         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23739
23740         for count in {1..100}; do
23741                 cancel_lru_locks
23742                 sync; sleep 0.2
23743
23744                 # read the lines of interest
23745                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23746                         error "df $inodes $dir | tail -n +2 failed"
23747                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23748                         error "lfs df $inodes $dir | grep summary: failed"
23749
23750                 # skip first substrings of each output as they are different
23751                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23752                 # compare the two outputs
23753                 passed=true
23754                 for i in {1..5}; do
23755                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23756                 done
23757                 $passed && break
23758         done
23759
23760         if ! $passed; then
23761                 df -P $inodes $dir
23762                 echo
23763                 lfs df $inodes $dir
23764                 error "df and lfs df $1 output mismatch: "      \
23765                       "df ${inodes}: ${df_out[*]}, "            \
23766                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23767         fi
23768 }
23769
23770 test_418() {
23771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23772
23773         local dir=$DIR/$tdir
23774         local numfiles=$((RANDOM % 4096 + 2))
23775         local numblocks=$((RANDOM % 256 + 1))
23776
23777         wait_delete_completed
23778         test_mkdir $dir
23779
23780         # check block output
23781         check_lfs_df blocks $dir
23782         # check inode output
23783         check_lfs_df inodes $dir
23784
23785         # create a single file and retest
23786         echo "Creating a single file and testing"
23787         createmany -o $dir/$tfile- 1 &>/dev/null ||
23788                 error "creating 1 file in $dir failed"
23789         check_lfs_df blocks $dir
23790         check_lfs_df inodes $dir
23791
23792         # create a random number of files
23793         echo "Creating $((numfiles - 1)) files and testing"
23794         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23795                 error "creating $((numfiles - 1)) files in $dir failed"
23796
23797         # write a random number of blocks to the first test file
23798         echo "Writing $numblocks 4K blocks and testing"
23799         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23800                 count=$numblocks &>/dev/null ||
23801                 error "dd to $dir/${tfile}-0 failed"
23802
23803         # retest
23804         check_lfs_df blocks $dir
23805         check_lfs_df inodes $dir
23806
23807         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23808                 error "unlinking $numfiles files in $dir failed"
23809 }
23810 run_test 418 "df and lfs df outputs match"
23811
23812 test_419()
23813 {
23814         local dir=$DIR/$tdir
23815
23816         mkdir -p $dir
23817         touch $dir/file
23818
23819         cancel_lru_locks mdc
23820
23821         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23822         $LCTL set_param fail_loc=0x1410
23823         cat $dir/file
23824         $LCTL set_param fail_loc=0
23825         rm -rf $dir
23826 }
23827 run_test 419 "Verify open file by name doesn't crash kernel"
23828
23829 test_420()
23830 {
23831         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23832                 skip "Need MDS version at least 2.12.53"
23833
23834         local SAVE_UMASK=$(umask)
23835         local dir=$DIR/$tdir
23836         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23837
23838         mkdir -p $dir
23839         umask 0000
23840         mkdir -m03777 $dir/testdir
23841         ls -dn $dir/testdir
23842         # Need to remove trailing '.' when SELinux is enabled
23843         local dirperms=$(ls -dn $dir/testdir |
23844                          awk '{ sub(/\.$/, "", $1); print $1}')
23845         [ $dirperms == "drwxrwsrwt" ] ||
23846                 error "incorrect perms on $dir/testdir"
23847
23848         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23849                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23850         ls -n $dir/testdir/testfile
23851         local fileperms=$(ls -n $dir/testdir/testfile |
23852                           awk '{ sub(/\.$/, "", $1); print $1}')
23853         [ $fileperms == "-rwxr-xr-x" ] ||
23854                 error "incorrect perms on $dir/testdir/testfile"
23855
23856         umask $SAVE_UMASK
23857 }
23858 run_test 420 "clear SGID bit on non-directories for non-members"
23859
23860 test_421a() {
23861         local cnt
23862         local fid1
23863         local fid2
23864
23865         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23866                 skip "Need MDS version at least 2.12.54"
23867
23868         test_mkdir $DIR/$tdir
23869         createmany -o $DIR/$tdir/f 3
23870         cnt=$(ls -1 $DIR/$tdir | wc -l)
23871         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23872
23873         fid1=$(lfs path2fid $DIR/$tdir/f1)
23874         fid2=$(lfs path2fid $DIR/$tdir/f2)
23875         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23876
23877         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23878         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23879
23880         cnt=$(ls -1 $DIR/$tdir | wc -l)
23881         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23882
23883         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23884         createmany -o $DIR/$tdir/f 3
23885         cnt=$(ls -1 $DIR/$tdir | wc -l)
23886         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23887
23888         fid1=$(lfs path2fid $DIR/$tdir/f1)
23889         fid2=$(lfs path2fid $DIR/$tdir/f2)
23890         echo "remove using fsname $FSNAME"
23891         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23892
23893         cnt=$(ls -1 $DIR/$tdir | wc -l)
23894         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23895 }
23896 run_test 421a "simple rm by fid"
23897
23898 test_421b() {
23899         local cnt
23900         local FID1
23901         local FID2
23902
23903         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23904                 skip "Need MDS version at least 2.12.54"
23905
23906         test_mkdir $DIR/$tdir
23907         createmany -o $DIR/$tdir/f 3
23908         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23909         MULTIPID=$!
23910
23911         FID1=$(lfs path2fid $DIR/$tdir/f1)
23912         FID2=$(lfs path2fid $DIR/$tdir/f2)
23913         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23914
23915         kill -USR1 $MULTIPID
23916         wait
23917
23918         cnt=$(ls $DIR/$tdir | wc -l)
23919         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23920 }
23921 run_test 421b "rm by fid on open file"
23922
23923 test_421c() {
23924         local cnt
23925         local FIDS
23926
23927         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23928                 skip "Need MDS version at least 2.12.54"
23929
23930         test_mkdir $DIR/$tdir
23931         createmany -o $DIR/$tdir/f 3
23932         touch $DIR/$tdir/$tfile
23933         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23934         cnt=$(ls -1 $DIR/$tdir | wc -l)
23935         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23936
23937         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23938         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23939
23940         cnt=$(ls $DIR/$tdir | wc -l)
23941         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23942 }
23943 run_test 421c "rm by fid against hardlinked files"
23944
23945 test_421d() {
23946         local cnt
23947         local FIDS
23948
23949         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23950                 skip "Need MDS version at least 2.12.54"
23951
23952         test_mkdir $DIR/$tdir
23953         createmany -o $DIR/$tdir/f 4097
23954         cnt=$(ls -1 $DIR/$tdir | wc -l)
23955         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23956
23957         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23958         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23959
23960         cnt=$(ls $DIR/$tdir | wc -l)
23961         rm -rf $DIR/$tdir
23962         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23963 }
23964 run_test 421d "rmfid en masse"
23965
23966 test_421e() {
23967         local cnt
23968         local FID
23969
23970         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23971         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23972                 skip "Need MDS version at least 2.12.54"
23973
23974         mkdir -p $DIR/$tdir
23975         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23976         createmany -o $DIR/$tdir/striped_dir/f 512
23977         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23978         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23979
23980         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23981                 sed "s/[/][^:]*://g")
23982         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23983
23984         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23985         rm -rf $DIR/$tdir
23986         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23987 }
23988 run_test 421e "rmfid in DNE"
23989
23990 test_421f() {
23991         local cnt
23992         local FID
23993
23994         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23995                 skip "Need MDS version at least 2.12.54"
23996
23997         test_mkdir $DIR/$tdir
23998         touch $DIR/$tdir/f
23999         cnt=$(ls -1 $DIR/$tdir | wc -l)
24000         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24001
24002         FID=$(lfs path2fid $DIR/$tdir/f)
24003         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24004         # rmfid should fail
24005         cnt=$(ls -1 $DIR/$tdir | wc -l)
24006         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24007
24008         chmod a+rw $DIR/$tdir
24009         ls -la $DIR/$tdir
24010         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24011         # rmfid should fail
24012         cnt=$(ls -1 $DIR/$tdir | wc -l)
24013         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24014
24015         rm -f $DIR/$tdir/f
24016         $RUNAS touch $DIR/$tdir/f
24017         FID=$(lfs path2fid $DIR/$tdir/f)
24018         echo "rmfid as root"
24019         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24020         cnt=$(ls -1 $DIR/$tdir | wc -l)
24021         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24022
24023         rm -f $DIR/$tdir/f
24024         $RUNAS touch $DIR/$tdir/f
24025         cnt=$(ls -1 $DIR/$tdir | wc -l)
24026         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24027         FID=$(lfs path2fid $DIR/$tdir/f)
24028         # rmfid w/o user_fid2path mount option should fail
24029         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24030         cnt=$(ls -1 $DIR/$tdir | wc -l)
24031         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24032
24033         umount_client $MOUNT || error "failed to umount client"
24034         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
24035                 error "failed to mount client'"
24036
24037         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
24038         # rmfid should succeed
24039         cnt=$(ls -1 $DIR/$tdir | wc -l)
24040         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24041
24042         # rmfid shouldn't allow to remove files due to dir's permission
24043         chmod a+rwx $DIR/$tdir
24044         touch $DIR/$tdir/f
24045         ls -la $DIR/$tdir
24046         FID=$(lfs path2fid $DIR/$tdir/f)
24047         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
24048
24049         umount_client $MOUNT || error "failed to umount client"
24050         mount_client $MOUNT "$MOUNT_OPTS" ||
24051                 error "failed to mount client'"
24052
24053 }
24054 run_test 421f "rmfid checks permissions"
24055
24056 test_421g() {
24057         local cnt
24058         local FIDS
24059
24060         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24061         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24062                 skip "Need MDS version at least 2.12.54"
24063
24064         mkdir -p $DIR/$tdir
24065         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24066         createmany -o $DIR/$tdir/striped_dir/f 512
24067         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24068         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24069
24070         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24071                 sed "s/[/][^:]*://g")
24072
24073         rm -f $DIR/$tdir/striped_dir/f1*
24074         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24075         removed=$((512 - cnt))
24076
24077         # few files have been just removed, so we expect
24078         # rmfid to fail on their fids
24079         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24080         [ $removed != $errors ] && error "$errors != $removed"
24081
24082         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24083         rm -rf $DIR/$tdir
24084         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24085 }
24086 run_test 421g "rmfid to return errors properly"
24087
24088 test_422() {
24089         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24090         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24091         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24092         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24093         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24094
24095         local amc=$(at_max_get client)
24096         local amo=$(at_max_get mds1)
24097         local timeout=`lctl get_param -n timeout`
24098
24099         at_max_set 0 client
24100         at_max_set 0 mds1
24101
24102 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24103         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24104                         fail_val=$(((2*timeout + 10)*1000))
24105         touch $DIR/$tdir/d3/file &
24106         sleep 2
24107 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24108         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24109                         fail_val=$((2*timeout + 5))
24110         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24111         local pid=$!
24112         sleep 1
24113         kill -9 $pid
24114         sleep $((2 * timeout))
24115         echo kill $pid
24116         kill -9 $pid
24117         lctl mark touch
24118         touch $DIR/$tdir/d2/file3
24119         touch $DIR/$tdir/d2/file4
24120         touch $DIR/$tdir/d2/file5
24121
24122         wait
24123         at_max_set $amc client
24124         at_max_set $amo mds1
24125
24126         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24127         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24128                 error "Watchdog is always throttled"
24129 }
24130 run_test 422 "kill a process with RPC in progress"
24131
24132 stat_test() {
24133     df -h $MOUNT &
24134     df -h $MOUNT &
24135     df -h $MOUNT &
24136     df -h $MOUNT &
24137     df -h $MOUNT &
24138     df -h $MOUNT &
24139 }
24140
24141 test_423() {
24142     local _stats
24143     # ensure statfs cache is expired
24144     sleep 2;
24145
24146     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24147     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24148
24149     return 0
24150 }
24151 run_test 423 "statfs should return a right data"
24152
24153 test_424() {
24154 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24155         $LCTL set_param fail_loc=0x80000522
24156         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24157         rm -f $DIR/$tfile
24158 }
24159 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24160
24161 test_425() {
24162         test_mkdir -c -1 $DIR/$tdir
24163         $LFS setstripe -c -1 $DIR/$tdir
24164
24165         lru_resize_disable "" 100
24166         stack_trap "lru_resize_enable" EXIT
24167
24168         sleep 5
24169
24170         for i in $(seq $((MDSCOUNT * 125))); do
24171                 local t=$DIR/$tdir/$tfile_$i
24172
24173                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24174                         error_noexit "Create file $t"
24175         done
24176         stack_trap "rm -rf $DIR/$tdir" EXIT
24177
24178         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24179                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24180                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24181
24182                 [ $lock_count -le $lru_size ] ||
24183                         error "osc lock count $lock_count > lru size $lru_size"
24184         done
24185
24186         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24187                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24188                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24189
24190                 [ $lock_count -le $lru_size ] ||
24191                         error "mdc lock count $lock_count > lru size $lru_size"
24192         done
24193 }
24194 run_test 425 "lock count should not exceed lru size"
24195
24196 test_426() {
24197         splice-test -r $DIR/$tfile
24198         splice-test -rd $DIR/$tfile
24199         splice-test $DIR/$tfile
24200         splice-test -d $DIR/$tfile
24201 }
24202 run_test 426 "splice test on Lustre"
24203
24204 test_427() {
24205         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24206         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24207                 skip "Need MDS version at least 2.12.4"
24208         local log
24209
24210         mkdir $DIR/$tdir
24211         mkdir $DIR/$tdir/1
24212         mkdir $DIR/$tdir/2
24213         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24214         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24215
24216         $LFS getdirstripe $DIR/$tdir/1/dir
24217
24218         #first setfattr for creating updatelog
24219         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24220
24221 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24222         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24223         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24224         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24225
24226         sleep 2
24227         fail mds2
24228         wait_recovery_complete mds2 $((2*TIMEOUT))
24229
24230         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24231         echo $log | grep "get update log failed" &&
24232                 error "update log corruption is detected" || true
24233 }
24234 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24235
24236 lseek_test_430() {
24237         local offset
24238         local file=$1
24239
24240         # data at [200K, 400K)
24241         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24242                 error "256K->512K dd fails"
24243         # data at [2M, 3M)
24244         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24245                 error "2M->3M dd fails"
24246         # data at [4M, 5M)
24247         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24248                 error "4M->5M dd fails"
24249         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24250         # start at first component hole #1
24251         printf "Seeking hole from 1000 ... "
24252         offset=$(lseek_test -l 1000 $file)
24253         echo $offset
24254         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24255         printf "Seeking data from 1000 ... "
24256         offset=$(lseek_test -d 1000 $file)
24257         echo $offset
24258         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24259
24260         # start at first component data block
24261         printf "Seeking hole from 300000 ... "
24262         offset=$(lseek_test -l 300000 $file)
24263         echo $offset
24264         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24265         printf "Seeking data from 300000 ... "
24266         offset=$(lseek_test -d 300000 $file)
24267         echo $offset
24268         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24269
24270         # start at the first component but beyond end of object size
24271         printf "Seeking hole from 1000000 ... "
24272         offset=$(lseek_test -l 1000000 $file)
24273         echo $offset
24274         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24275         printf "Seeking data from 1000000 ... "
24276         offset=$(lseek_test -d 1000000 $file)
24277         echo $offset
24278         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24279
24280         # start at second component stripe 2 (empty file)
24281         printf "Seeking hole from 1500000 ... "
24282         offset=$(lseek_test -l 1500000 $file)
24283         echo $offset
24284         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24285         printf "Seeking data from 1500000 ... "
24286         offset=$(lseek_test -d 1500000 $file)
24287         echo $offset
24288         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24289
24290         # start at second component stripe 1 (all data)
24291         printf "Seeking hole from 3000000 ... "
24292         offset=$(lseek_test -l 3000000 $file)
24293         echo $offset
24294         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24295         printf "Seeking data from 3000000 ... "
24296         offset=$(lseek_test -d 3000000 $file)
24297         echo $offset
24298         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24299
24300         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24301                 error "2nd dd fails"
24302         echo "Add data block at 640K...1280K"
24303
24304         # start at before new data block, in hole
24305         printf "Seeking hole from 600000 ... "
24306         offset=$(lseek_test -l 600000 $file)
24307         echo $offset
24308         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24309         printf "Seeking data from 600000 ... "
24310         offset=$(lseek_test -d 600000 $file)
24311         echo $offset
24312         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24313
24314         # start at the first component new data block
24315         printf "Seeking hole from 1000000 ... "
24316         offset=$(lseek_test -l 1000000 $file)
24317         echo $offset
24318         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24319         printf "Seeking data from 1000000 ... "
24320         offset=$(lseek_test -d 1000000 $file)
24321         echo $offset
24322         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24323
24324         # start at second component stripe 2, new data
24325         printf "Seeking hole from 1200000 ... "
24326         offset=$(lseek_test -l 1200000 $file)
24327         echo $offset
24328         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24329         printf "Seeking data from 1200000 ... "
24330         offset=$(lseek_test -d 1200000 $file)
24331         echo $offset
24332         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24333
24334         # start beyond file end
24335         printf "Using offset > filesize ... "
24336         lseek_test -l 4000000 $file && error "lseek should fail"
24337         printf "Using offset > filesize ... "
24338         lseek_test -d 4000000 $file && error "lseek should fail"
24339
24340         printf "Done\n\n"
24341 }
24342
24343 test_430a() {
24344         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24345                 skip "MDT does not support SEEK_HOLE"
24346
24347         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24348                 skip "OST does not support SEEK_HOLE"
24349
24350         local file=$DIR/$tdir/$tfile
24351
24352         mkdir -p $DIR/$tdir
24353
24354         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24355         # OST stripe #1 will have continuous data at [1M, 3M)
24356         # OST stripe #2 is empty
24357         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24358         lseek_test_430 $file
24359         rm $file
24360         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24361         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24362         lseek_test_430 $file
24363         rm $file
24364         $LFS setstripe -c2 -S 512K $file
24365         echo "Two stripes, stripe size 512K"
24366         lseek_test_430 $file
24367         rm $file
24368         # FLR with stale mirror
24369         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24370                        -N -c2 -S 1M $file
24371         echo "Mirrored file:"
24372         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24373         echo "Plain 2 stripes 1M"
24374         lseek_test_430 $file
24375         rm $file
24376 }
24377 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24378
24379 test_430b() {
24380         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24381                 skip "OST does not support SEEK_HOLE"
24382
24383         local offset
24384         local file=$DIR/$tdir/$tfile
24385
24386         mkdir -p $DIR/$tdir
24387         # Empty layout lseek should fail
24388         $MCREATE $file
24389         # seek from 0
24390         printf "Seeking hole from 0 ... "
24391         lseek_test -l 0 $file && error "lseek should fail"
24392         printf "Seeking data from 0 ... "
24393         lseek_test -d 0 $file && error "lseek should fail"
24394         rm $file
24395
24396         # 1M-hole file
24397         $LFS setstripe -E 1M -c2 -E eof $file
24398         $TRUNCATE $file 1048576
24399         printf "Seeking hole from 1000000 ... "
24400         offset=$(lseek_test -l 1000000 $file)
24401         echo $offset
24402         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24403         printf "Seeking data from 1000000 ... "
24404         lseek_test -d 1000000 $file && error "lseek should fail"
24405         rm $file
24406
24407         # full component followed by non-inited one
24408         $LFS setstripe -E 1M -c2 -E eof $file
24409         dd if=/dev/urandom of=$file bs=1M count=1
24410         printf "Seeking hole from 1000000 ... "
24411         offset=$(lseek_test -l 1000000 $file)
24412         echo $offset
24413         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24414         printf "Seeking hole from 1048576 ... "
24415         lseek_test -l 1048576 $file && error "lseek should fail"
24416         # init second component and truncate back
24417         echo "123" >> $file
24418         $TRUNCATE $file 1048576
24419         printf "Seeking hole from 1000000 ... "
24420         offset=$(lseek_test -l 1000000 $file)
24421         echo $offset
24422         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24423         printf "Seeking hole from 1048576 ... "
24424         lseek_test -l 1048576 $file && error "lseek should fail"
24425         # boundary checks for big values
24426         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24427         offset=$(lseek_test -d 0 $file.10g)
24428         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24429         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24430         offset=$(lseek_test -d 0 $file.100g)
24431         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24432         return 0
24433 }
24434 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24435
24436 test_430c() {
24437         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24438                 skip "OST does not support SEEK_HOLE"
24439
24440         local file=$DIR/$tdir/$tfile
24441         local start
24442
24443         mkdir -p $DIR/$tdir
24444         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24445
24446         # cp version 8.33+ prefers lseek over fiemap
24447         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24448                 start=$SECONDS
24449                 time cp $file /dev/null
24450                 (( SECONDS - start < 5 )) ||
24451                         error "cp: too long runtime $((SECONDS - start))"
24452
24453         fi
24454         # tar version 1.29+ supports SEEK_HOLE/DATA
24455         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24456                 start=$SECONDS
24457                 time tar cS $file - | cat > /dev/null
24458                 (( SECONDS - start < 5 )) ||
24459                         error "tar: too long runtime $((SECONDS - start))"
24460         fi
24461 }
24462 run_test 430c "lseek: external tools check"
24463
24464 test_431() { # LU-14187
24465         local file=$DIR/$tdir/$tfile
24466
24467         mkdir -p $DIR/$tdir
24468         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24469         dd if=/dev/urandom of=$file bs=4k count=1
24470         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24471         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24472         #define OBD_FAIL_OST_RESTART_IO 0x251
24473         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24474         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24475         cp $file $file.0
24476         cancel_lru_locks
24477         sync_all_data
24478         echo 3 > /proc/sys/vm/drop_caches
24479         diff  $file $file.0 || error "data diff"
24480 }
24481 run_test 431 "Restart transaction for IO"
24482
24483 prep_801() {
24484         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24485         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24486                 skip "Need server version at least 2.9.55"
24487
24488         start_full_debug_logging
24489 }
24490
24491 post_801() {
24492         stop_full_debug_logging
24493 }
24494
24495 barrier_stat() {
24496         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24497                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24498                            awk '/The barrier for/ { print $7 }')
24499                 echo $st
24500         else
24501                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24502                 echo \'$st\'
24503         fi
24504 }
24505
24506 barrier_expired() {
24507         local expired
24508
24509         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24510                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24511                           awk '/will be expired/ { print $7 }')
24512         else
24513                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24514         fi
24515
24516         echo $expired
24517 }
24518
24519 test_801a() {
24520         prep_801
24521
24522         echo "Start barrier_freeze at: $(date)"
24523         #define OBD_FAIL_BARRIER_DELAY          0x2202
24524         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24525         # Do not reduce barrier time - See LU-11873
24526         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24527
24528         sleep 2
24529         local b_status=$(barrier_stat)
24530         echo "Got barrier status at: $(date)"
24531         [ "$b_status" = "'freezing_p1'" ] ||
24532                 error "(1) unexpected barrier status $b_status"
24533
24534         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24535         wait
24536         b_status=$(barrier_stat)
24537         [ "$b_status" = "'frozen'" ] ||
24538                 error "(2) unexpected barrier status $b_status"
24539
24540         local expired=$(barrier_expired)
24541         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24542         sleep $((expired + 3))
24543
24544         b_status=$(barrier_stat)
24545         [ "$b_status" = "'expired'" ] ||
24546                 error "(3) unexpected barrier status $b_status"
24547
24548         # Do not reduce barrier time - See LU-11873
24549         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24550                 error "(4) fail to freeze barrier"
24551
24552         b_status=$(barrier_stat)
24553         [ "$b_status" = "'frozen'" ] ||
24554                 error "(5) unexpected barrier status $b_status"
24555
24556         echo "Start barrier_thaw at: $(date)"
24557         #define OBD_FAIL_BARRIER_DELAY          0x2202
24558         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24559         do_facet mgs $LCTL barrier_thaw $FSNAME &
24560
24561         sleep 2
24562         b_status=$(barrier_stat)
24563         echo "Got barrier status at: $(date)"
24564         [ "$b_status" = "'thawing'" ] ||
24565                 error "(6) unexpected barrier status $b_status"
24566
24567         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24568         wait
24569         b_status=$(barrier_stat)
24570         [ "$b_status" = "'thawed'" ] ||
24571                 error "(7) unexpected barrier status $b_status"
24572
24573         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24574         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24575         do_facet mgs $LCTL barrier_freeze $FSNAME
24576
24577         b_status=$(barrier_stat)
24578         [ "$b_status" = "'failed'" ] ||
24579                 error "(8) unexpected barrier status $b_status"
24580
24581         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24582         do_facet mgs $LCTL barrier_thaw $FSNAME
24583
24584         post_801
24585 }
24586 run_test 801a "write barrier user interfaces and stat machine"
24587
24588 test_801b() {
24589         prep_801
24590
24591         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24592         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24593         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24594         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24595         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24596
24597         cancel_lru_locks mdc
24598
24599         # 180 seconds should be long enough
24600         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24601
24602         local b_status=$(barrier_stat)
24603         [ "$b_status" = "'frozen'" ] ||
24604                 error "(6) unexpected barrier status $b_status"
24605
24606         mkdir $DIR/$tdir/d0/d10 &
24607         mkdir_pid=$!
24608
24609         touch $DIR/$tdir/d1/f13 &
24610         touch_pid=$!
24611
24612         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24613         ln_pid=$!
24614
24615         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24616         mv_pid=$!
24617
24618         rm -f $DIR/$tdir/d4/f12 &
24619         rm_pid=$!
24620
24621         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24622
24623         # To guarantee taht the 'stat' is not blocked
24624         b_status=$(barrier_stat)
24625         [ "$b_status" = "'frozen'" ] ||
24626                 error "(8) unexpected barrier status $b_status"
24627
24628         # let above commands to run at background
24629         sleep 5
24630
24631         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24632         ps -p $touch_pid || error "(10) touch should be blocked"
24633         ps -p $ln_pid || error "(11) link should be blocked"
24634         ps -p $mv_pid || error "(12) rename should be blocked"
24635         ps -p $rm_pid || error "(13) unlink should be blocked"
24636
24637         b_status=$(barrier_stat)
24638         [ "$b_status" = "'frozen'" ] ||
24639                 error "(14) unexpected barrier status $b_status"
24640
24641         do_facet mgs $LCTL barrier_thaw $FSNAME
24642         b_status=$(barrier_stat)
24643         [ "$b_status" = "'thawed'" ] ||
24644                 error "(15) unexpected barrier status $b_status"
24645
24646         wait $mkdir_pid || error "(16) mkdir should succeed"
24647         wait $touch_pid || error "(17) touch should succeed"
24648         wait $ln_pid || error "(18) link should succeed"
24649         wait $mv_pid || error "(19) rename should succeed"
24650         wait $rm_pid || error "(20) unlink should succeed"
24651
24652         post_801
24653 }
24654 run_test 801b "modification will be blocked by write barrier"
24655
24656 test_801c() {
24657         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24658
24659         prep_801
24660
24661         stop mds2 || error "(1) Fail to stop mds2"
24662
24663         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24664
24665         local b_status=$(barrier_stat)
24666         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24667                 do_facet mgs $LCTL barrier_thaw $FSNAME
24668                 error "(2) unexpected barrier status $b_status"
24669         }
24670
24671         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24672                 error "(3) Fail to rescan barrier bitmap"
24673
24674         # Do not reduce barrier time - See LU-11873
24675         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24676
24677         b_status=$(barrier_stat)
24678         [ "$b_status" = "'frozen'" ] ||
24679                 error "(4) unexpected barrier status $b_status"
24680
24681         do_facet mgs $LCTL barrier_thaw $FSNAME
24682         b_status=$(barrier_stat)
24683         [ "$b_status" = "'thawed'" ] ||
24684                 error "(5) unexpected barrier status $b_status"
24685
24686         local devname=$(mdsdevname 2)
24687
24688         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24689
24690         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24691                 error "(7) Fail to rescan barrier bitmap"
24692
24693         post_801
24694 }
24695 run_test 801c "rescan barrier bitmap"
24696
24697 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24698 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24699 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24700 saved_MOUNT_OPTS=$MOUNT_OPTS
24701
24702 cleanup_802a() {
24703         trap 0
24704
24705         stopall
24706         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24707         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24708         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24709         MOUNT_OPTS=$saved_MOUNT_OPTS
24710         setupall
24711 }
24712
24713 test_802a() {
24714         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24715         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24716         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24717                 skip "Need server version at least 2.9.55"
24718
24719         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24720
24721         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24722
24723         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24724                 error "(2) Fail to copy"
24725
24726         trap cleanup_802a EXIT
24727
24728         # sync by force before remount as readonly
24729         sync; sync_all_data; sleep 3; sync_all_data
24730
24731         stopall
24732
24733         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24734         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24735         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24736
24737         echo "Mount the server as read only"
24738         setupall server_only || error "(3) Fail to start servers"
24739
24740         echo "Mount client without ro should fail"
24741         mount_client $MOUNT &&
24742                 error "(4) Mount client without 'ro' should fail"
24743
24744         echo "Mount client with ro should succeed"
24745         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24746         mount_client $MOUNT ||
24747                 error "(5) Mount client with 'ro' should succeed"
24748
24749         echo "Modify should be refused"
24750         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24751
24752         echo "Read should be allowed"
24753         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24754                 error "(7) Read should succeed under ro mode"
24755
24756         cleanup_802a
24757 }
24758 run_test 802a "simulate readonly device"
24759
24760 test_802b() {
24761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24762         remote_mds_nodsh && skip "remote MDS with nodsh"
24763
24764         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24765                 skip "readonly option not available"
24766
24767         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24768
24769         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24770                 error "(2) Fail to copy"
24771
24772         # write back all cached data before setting MDT to readonly
24773         cancel_lru_locks
24774         sync_all_data
24775
24776         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24777         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24778
24779         echo "Modify should be refused"
24780         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24781
24782         echo "Read should be allowed"
24783         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24784                 error "(7) Read should succeed under ro mode"
24785
24786         # disable readonly
24787         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24788 }
24789 run_test 802b "be able to set MDTs to readonly"
24790
24791 test_803a() {
24792         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24793         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24794                 skip "MDS needs to be newer than 2.10.54"
24795
24796         mkdir -p $DIR/$tdir
24797         # Create some objects on all MDTs to trigger related logs objects
24798         for idx in $(seq $MDSCOUNT); do
24799                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24800                         $DIR/$tdir/dir${idx} ||
24801                         error "Fail to create $DIR/$tdir/dir${idx}"
24802         done
24803
24804         sync; sleep 3
24805         wait_delete_completed # ensure old test cleanups are finished
24806         echo "before create:"
24807         $LFS df -i $MOUNT
24808         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24809
24810         for i in {1..10}; do
24811                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24812                         error "Fail to create $DIR/$tdir/foo$i"
24813         done
24814
24815         sync; sleep 3
24816         echo "after create:"
24817         $LFS df -i $MOUNT
24818         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24819
24820         # allow for an llog to be cleaned up during the test
24821         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24822                 error "before ($before_used) + 10 > after ($after_used)"
24823
24824         for i in {1..10}; do
24825                 rm -rf $DIR/$tdir/foo$i ||
24826                         error "Fail to remove $DIR/$tdir/foo$i"
24827         done
24828
24829         sleep 3 # avoid MDT return cached statfs
24830         wait_delete_completed
24831         echo "after unlink:"
24832         $LFS df -i $MOUNT
24833         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24834
24835         # allow for an llog to be created during the test
24836         [ $after_used -le $((before_used + 1)) ] ||
24837                 error "after ($after_used) > before ($before_used) + 1"
24838 }
24839 run_test 803a "verify agent object for remote object"
24840
24841 test_803b() {
24842         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24843         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24844                 skip "MDS needs to be newer than 2.13.56"
24845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24846
24847         for i in $(seq 0 $((MDSCOUNT - 1))); do
24848                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24849         done
24850
24851         local before=0
24852         local after=0
24853
24854         local tmp
24855
24856         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24857         for i in $(seq 0 $((MDSCOUNT - 1))); do
24858                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24859                         awk '/getattr/ { print $2 }')
24860                 before=$((before + tmp))
24861         done
24862         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24863         for i in $(seq 0 $((MDSCOUNT - 1))); do
24864                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24865                         awk '/getattr/ { print $2 }')
24866                 after=$((after + tmp))
24867         done
24868
24869         [ $before -eq $after ] || error "getattr count $before != $after"
24870 }
24871 run_test 803b "remote object can getattr from cache"
24872
24873 test_804() {
24874         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24875         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24876                 skip "MDS needs to be newer than 2.10.54"
24877         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24878
24879         mkdir -p $DIR/$tdir
24880         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24881                 error "Fail to create $DIR/$tdir/dir0"
24882
24883         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24884         local dev=$(mdsdevname 2)
24885
24886         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24887                 grep ${fid} || error "NOT found agent entry for dir0"
24888
24889         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24890                 error "Fail to create $DIR/$tdir/dir1"
24891
24892         touch $DIR/$tdir/dir1/foo0 ||
24893                 error "Fail to create $DIR/$tdir/dir1/foo0"
24894         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24895         local rc=0
24896
24897         for idx in $(seq $MDSCOUNT); do
24898                 dev=$(mdsdevname $idx)
24899                 do_facet mds${idx} \
24900                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24901                         grep ${fid} && rc=$idx
24902         done
24903
24904         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24905                 error "Fail to rename foo0 to foo1"
24906         if [ $rc -eq 0 ]; then
24907                 for idx in $(seq $MDSCOUNT); do
24908                         dev=$(mdsdevname $idx)
24909                         do_facet mds${idx} \
24910                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24911                         grep ${fid} && rc=$idx
24912                 done
24913         fi
24914
24915         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24916                 error "Fail to rename foo1 to foo2"
24917         if [ $rc -eq 0 ]; then
24918                 for idx in $(seq $MDSCOUNT); do
24919                         dev=$(mdsdevname $idx)
24920                         do_facet mds${idx} \
24921                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24922                         grep ${fid} && rc=$idx
24923                 done
24924         fi
24925
24926         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24927
24928         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24929                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24930         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24931                 error "Fail to rename foo2 to foo0"
24932         unlink $DIR/$tdir/dir1/foo0 ||
24933                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24934         rm -rf $DIR/$tdir/dir0 ||
24935                 error "Fail to rm $DIR/$tdir/dir0"
24936
24937         for idx in $(seq $MDSCOUNT); do
24938                 dev=$(mdsdevname $idx)
24939                 rc=0
24940
24941                 stop mds${idx}
24942                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24943                         rc=$?
24944                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24945                         error "mount mds$idx failed"
24946                 df $MOUNT > /dev/null 2>&1
24947
24948                 # e2fsck should not return error
24949                 [ $rc -eq 0 ] ||
24950                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24951         done
24952 }
24953 run_test 804 "verify agent entry for remote entry"
24954
24955 cleanup_805() {
24956         do_facet $SINGLEMDS zfs set quota=$old $fsset
24957         unlinkmany $DIR/$tdir/f- 1000000
24958         trap 0
24959 }
24960
24961 test_805() {
24962         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24963         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24964         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24965                 skip "netfree not implemented before 0.7"
24966         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24967                 skip "Need MDS version at least 2.10.57"
24968
24969         local fsset
24970         local freekb
24971         local usedkb
24972         local old
24973         local quota
24974         local pref="osd-zfs.$FSNAME-MDT0000."
24975
24976         # limit available space on MDS dataset to meet nospace issue
24977         # quickly. then ZFS 0.7.2 can use reserved space if asked
24978         # properly (using netfree flag in osd_declare_destroy()
24979         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24980         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24981                 gawk '{print $3}')
24982         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24983         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24984         let "usedkb=usedkb-freekb"
24985         let "freekb=freekb/2"
24986         if let "freekb > 5000"; then
24987                 let "freekb=5000"
24988         fi
24989         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24990         trap cleanup_805 EXIT
24991         mkdir $DIR/$tdir
24992         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24993                 error "Can't set PFL layout"
24994         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24995         rm -rf $DIR/$tdir || error "not able to remove"
24996         do_facet $SINGLEMDS zfs set quota=$old $fsset
24997         trap 0
24998 }
24999 run_test 805 "ZFS can remove from full fs"
25000
25001 # Size-on-MDS test
25002 check_lsom_data()
25003 {
25004         local file=$1
25005         local size=$($LFS getsom -s $file)
25006         local expect=$(stat -c %s $file)
25007
25008         [[ $size == $expect ]] ||
25009                 error "$file expected size: $expect, got: $size"
25010
25011         local blocks=$($LFS getsom -b $file)
25012         expect=$(stat -c %b $file)
25013         [[ $blocks == $expect ]] ||
25014                 error "$file expected blocks: $expect, got: $blocks"
25015 }
25016
25017 check_lsom_size()
25018 {
25019         local size=$($LFS getsom -s $1)
25020         local expect=$2
25021
25022         [[ $size == $expect ]] ||
25023                 error "$file expected size: $expect, got: $size"
25024 }
25025
25026 test_806() {
25027         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25028                 skip "Need MDS version at least 2.11.52"
25029
25030         local bs=1048576
25031
25032         touch $DIR/$tfile || error "touch $tfile failed"
25033
25034         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25035         save_lustre_params client "llite.*.xattr_cache" > $save
25036         lctl set_param llite.*.xattr_cache=0
25037         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25038
25039         # single-threaded write
25040         echo "Test SOM for single-threaded write"
25041         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25042                 error "write $tfile failed"
25043         check_lsom_size $DIR/$tfile $bs
25044
25045         local num=32
25046         local size=$(($num * $bs))
25047         local offset=0
25048         local i
25049
25050         echo "Test SOM for single client multi-threaded($num) write"
25051         $TRUNCATE $DIR/$tfile 0
25052         for ((i = 0; i < $num; i++)); do
25053                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25054                 local pids[$i]=$!
25055                 offset=$((offset + $bs))
25056         done
25057         for (( i=0; i < $num; i++ )); do
25058                 wait ${pids[$i]}
25059         done
25060         check_lsom_size $DIR/$tfile $size
25061
25062         $TRUNCATE $DIR/$tfile 0
25063         for ((i = 0; i < $num; i++)); do
25064                 offset=$((offset - $bs))
25065                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25066                 local pids[$i]=$!
25067         done
25068         for (( i=0; i < $num; i++ )); do
25069                 wait ${pids[$i]}
25070         done
25071         check_lsom_size $DIR/$tfile $size
25072
25073         # multi-client writes
25074         num=$(get_node_count ${CLIENTS//,/ })
25075         size=$(($num * $bs))
25076         offset=0
25077         i=0
25078
25079         echo "Test SOM for multi-client ($num) writes"
25080         $TRUNCATE $DIR/$tfile 0
25081         for client in ${CLIENTS//,/ }; do
25082                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25083                 local pids[$i]=$!
25084                 i=$((i + 1))
25085                 offset=$((offset + $bs))
25086         done
25087         for (( i=0; i < $num; i++ )); do
25088                 wait ${pids[$i]}
25089         done
25090         check_lsom_size $DIR/$tfile $offset
25091
25092         i=0
25093         $TRUNCATE $DIR/$tfile 0
25094         for client in ${CLIENTS//,/ }; do
25095                 offset=$((offset - $bs))
25096                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25097                 local pids[$i]=$!
25098                 i=$((i + 1))
25099         done
25100         for (( i=0; i < $num; i++ )); do
25101                 wait ${pids[$i]}
25102         done
25103         check_lsom_size $DIR/$tfile $size
25104
25105         # verify truncate
25106         echo "Test SOM for truncate"
25107         $TRUNCATE $DIR/$tfile 1048576
25108         check_lsom_size $DIR/$tfile 1048576
25109         $TRUNCATE $DIR/$tfile 1234
25110         check_lsom_size $DIR/$tfile 1234
25111
25112         # verify SOM blocks count
25113         echo "Verify SOM block count"
25114         $TRUNCATE $DIR/$tfile 0
25115         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25116                 error "failed to write file $tfile"
25117         check_lsom_data $DIR/$tfile
25118 }
25119 run_test 806 "Verify Lazy Size on MDS"
25120
25121 test_807() {
25122         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25123         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25124                 skip "Need MDS version at least 2.11.52"
25125
25126         # Registration step
25127         changelog_register || error "changelog_register failed"
25128         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25129         changelog_users $SINGLEMDS | grep -q $cl_user ||
25130                 error "User $cl_user not found in changelog_users"
25131
25132         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25133         save_lustre_params client "llite.*.xattr_cache" > $save
25134         lctl set_param llite.*.xattr_cache=0
25135         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25136
25137         rm -rf $DIR/$tdir || error "rm $tdir failed"
25138         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25139         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25140         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25141         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25142                 error "truncate $tdir/trunc failed"
25143
25144         local bs=1048576
25145         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25146                 error "write $tfile failed"
25147
25148         # multi-client wirtes
25149         local num=$(get_node_count ${CLIENTS//,/ })
25150         local offset=0
25151         local i=0
25152
25153         echo "Test SOM for multi-client ($num) writes"
25154         touch $DIR/$tfile || error "touch $tfile failed"
25155         $TRUNCATE $DIR/$tfile 0
25156         for client in ${CLIENTS//,/ }; do
25157                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25158                 local pids[$i]=$!
25159                 i=$((i + 1))
25160                 offset=$((offset + $bs))
25161         done
25162         for (( i=0; i < $num; i++ )); do
25163                 wait ${pids[$i]}
25164         done
25165
25166         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25167         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25168         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25169         check_lsom_data $DIR/$tdir/trunc
25170         check_lsom_data $DIR/$tdir/single_dd
25171         check_lsom_data $DIR/$tfile
25172
25173         rm -rf $DIR/$tdir
25174         # Deregistration step
25175         changelog_deregister || error "changelog_deregister failed"
25176 }
25177 run_test 807 "verify LSOM syncing tool"
25178
25179 check_som_nologged()
25180 {
25181         local lines=$($LFS changelog $FSNAME-MDT0000 |
25182                 grep 'x=trusted.som' | wc -l)
25183         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25184 }
25185
25186 test_808() {
25187         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25188                 skip "Need MDS version at least 2.11.55"
25189
25190         # Registration step
25191         changelog_register || error "changelog_register failed"
25192
25193         touch $DIR/$tfile || error "touch $tfile failed"
25194         check_som_nologged
25195
25196         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25197                 error "write $tfile failed"
25198         check_som_nologged
25199
25200         $TRUNCATE $DIR/$tfile 1234
25201         check_som_nologged
25202
25203         $TRUNCATE $DIR/$tfile 1048576
25204         check_som_nologged
25205
25206         # Deregistration step
25207         changelog_deregister || error "changelog_deregister failed"
25208 }
25209 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25210
25211 check_som_nodata()
25212 {
25213         $LFS getsom $1
25214         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25215 }
25216
25217 test_809() {
25218         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25219                 skip "Need MDS version at least 2.11.56"
25220
25221         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25222                 error "failed to create DoM-only file $DIR/$tfile"
25223         touch $DIR/$tfile || error "touch $tfile failed"
25224         check_som_nodata $DIR/$tfile
25225
25226         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25227                 error "write $tfile failed"
25228         check_som_nodata $DIR/$tfile
25229
25230         $TRUNCATE $DIR/$tfile 1234
25231         check_som_nodata $DIR/$tfile
25232
25233         $TRUNCATE $DIR/$tfile 4097
25234         check_som_nodata $DIR/$file
25235 }
25236 run_test 809 "Verify no SOM xattr store for DoM-only files"
25237
25238 test_810() {
25239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25240         $GSS && skip_env "could not run with gss"
25241         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25242                 skip "OST < 2.12.58 doesn't align checksum"
25243
25244         set_checksums 1
25245         stack_trap "set_checksums $ORIG_CSUM" EXIT
25246         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25247
25248         local csum
25249         local before
25250         local after
25251         for csum in $CKSUM_TYPES; do
25252                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25253                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25254                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25255                         eval set -- $i
25256                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25257                         before=$(md5sum $DIR/$tfile)
25258                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25259                         after=$(md5sum $DIR/$tfile)
25260                         [ "$before" == "$after" ] ||
25261                                 error "$csum: $before != $after bs=$1 seek=$2"
25262                 done
25263         done
25264 }
25265 run_test 810 "partial page writes on ZFS (LU-11663)"
25266
25267 test_812a() {
25268         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25269                 skip "OST < 2.12.51 doesn't support this fail_loc"
25270
25271         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25272         # ensure ost1 is connected
25273         stat $DIR/$tfile >/dev/null || error "can't stat"
25274         wait_osc_import_state client ost1 FULL
25275         # no locks, no reqs to let the connection idle
25276         cancel_lru_locks osc
25277
25278         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25279 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25280         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25281         wait_osc_import_state client ost1 CONNECTING
25282         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25283
25284         stat $DIR/$tfile >/dev/null || error "can't stat file"
25285 }
25286 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25287
25288 test_812b() { # LU-12378
25289         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25290                 skip "OST < 2.12.51 doesn't support this fail_loc"
25291
25292         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25293         # ensure ost1 is connected
25294         stat $DIR/$tfile >/dev/null || error "can't stat"
25295         wait_osc_import_state client ost1 FULL
25296         # no locks, no reqs to let the connection idle
25297         cancel_lru_locks osc
25298
25299         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25300 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25301         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25302         wait_osc_import_state client ost1 CONNECTING
25303         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25304
25305         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25306         wait_osc_import_state client ost1 IDLE
25307 }
25308 run_test 812b "do not drop no resend request for idle connect"
25309
25310 test_813() {
25311         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25312         [ -z "$file_heat_sav" ] && skip "no file heat support"
25313
25314         local readsample
25315         local writesample
25316         local readbyte
25317         local writebyte
25318         local readsample1
25319         local writesample1
25320         local readbyte1
25321         local writebyte1
25322
25323         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25324         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25325
25326         $LCTL set_param -n llite.*.file_heat=1
25327         echo "Turn on file heat"
25328         echo "Period second: $period_second, Decay percentage: $decay_pct"
25329
25330         echo "QQQQ" > $DIR/$tfile
25331         echo "QQQQ" > $DIR/$tfile
25332         echo "QQQQ" > $DIR/$tfile
25333         cat $DIR/$tfile > /dev/null
25334         cat $DIR/$tfile > /dev/null
25335         cat $DIR/$tfile > /dev/null
25336         cat $DIR/$tfile > /dev/null
25337
25338         local out=$($LFS heat_get $DIR/$tfile)
25339
25340         $LFS heat_get $DIR/$tfile
25341         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25342         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25343         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25344         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25345
25346         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25347         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25348         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25349         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25350
25351         sleep $((period_second + 3))
25352         echo "Sleep $((period_second + 3)) seconds..."
25353         # The recursion formula to calculate the heat of the file f is as
25354         # follow:
25355         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25356         # Where Hi is the heat value in the period between time points i*I and
25357         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25358         # to the weight of Ci.
25359         out=$($LFS heat_get $DIR/$tfile)
25360         $LFS heat_get $DIR/$tfile
25361         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25362         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25363         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25364         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25365
25366         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25367                 error "read sample ($readsample) is wrong"
25368         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25369                 error "write sample ($writesample) is wrong"
25370         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25371                 error "read bytes ($readbyte) is wrong"
25372         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25373                 error "write bytes ($writebyte) is wrong"
25374
25375         echo "QQQQ" > $DIR/$tfile
25376         echo "QQQQ" > $DIR/$tfile
25377         echo "QQQQ" > $DIR/$tfile
25378         cat $DIR/$tfile > /dev/null
25379         cat $DIR/$tfile > /dev/null
25380         cat $DIR/$tfile > /dev/null
25381         cat $DIR/$tfile > /dev/null
25382
25383         sleep $((period_second + 3))
25384         echo "Sleep $((period_second + 3)) seconds..."
25385
25386         out=$($LFS heat_get $DIR/$tfile)
25387         $LFS heat_get $DIR/$tfile
25388         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25389         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25390         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25391         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25392
25393         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25394                 4 * $decay_pct) / 100") -eq 1 ] ||
25395                 error "read sample ($readsample1) is wrong"
25396         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25397                 3 * $decay_pct) / 100") -eq 1 ] ||
25398                 error "write sample ($writesample1) is wrong"
25399         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25400                 20 * $decay_pct) / 100") -eq 1 ] ||
25401                 error "read bytes ($readbyte1) is wrong"
25402         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25403                 15 * $decay_pct) / 100") -eq 1 ] ||
25404                 error "write bytes ($writebyte1) is wrong"
25405
25406         echo "Turn off file heat for the file $DIR/$tfile"
25407         $LFS heat_set -o $DIR/$tfile
25408
25409         echo "QQQQ" > $DIR/$tfile
25410         echo "QQQQ" > $DIR/$tfile
25411         echo "QQQQ" > $DIR/$tfile
25412         cat $DIR/$tfile > /dev/null
25413         cat $DIR/$tfile > /dev/null
25414         cat $DIR/$tfile > /dev/null
25415         cat $DIR/$tfile > /dev/null
25416
25417         out=$($LFS heat_get $DIR/$tfile)
25418         $LFS heat_get $DIR/$tfile
25419         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25420         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25421         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25422         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25423
25424         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25425         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25426         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25427         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25428
25429         echo "Trun on file heat for the file $DIR/$tfile"
25430         $LFS heat_set -O $DIR/$tfile
25431
25432         echo "QQQQ" > $DIR/$tfile
25433         echo "QQQQ" > $DIR/$tfile
25434         echo "QQQQ" > $DIR/$tfile
25435         cat $DIR/$tfile > /dev/null
25436         cat $DIR/$tfile > /dev/null
25437         cat $DIR/$tfile > /dev/null
25438         cat $DIR/$tfile > /dev/null
25439
25440         out=$($LFS heat_get $DIR/$tfile)
25441         $LFS heat_get $DIR/$tfile
25442         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25443         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25444         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25445         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25446
25447         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25448         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25449         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25450         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25451
25452         $LFS heat_set -c $DIR/$tfile
25453         $LCTL set_param -n llite.*.file_heat=0
25454         echo "Turn off file heat support for the Lustre filesystem"
25455
25456         echo "QQQQ" > $DIR/$tfile
25457         echo "QQQQ" > $DIR/$tfile
25458         echo "QQQQ" > $DIR/$tfile
25459         cat $DIR/$tfile > /dev/null
25460         cat $DIR/$tfile > /dev/null
25461         cat $DIR/$tfile > /dev/null
25462         cat $DIR/$tfile > /dev/null
25463
25464         out=$($LFS heat_get $DIR/$tfile)
25465         $LFS heat_get $DIR/$tfile
25466         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25467         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25468         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25469         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25470
25471         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25472         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25473         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25474         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25475
25476         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25477         rm -f $DIR/$tfile
25478 }
25479 run_test 813 "File heat verfication"
25480
25481 test_814()
25482 {
25483         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25484         echo -n y >> $DIR/$tfile
25485         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25486         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25487 }
25488 run_test 814 "sparse cp works as expected (LU-12361)"
25489
25490 test_815()
25491 {
25492         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25493         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25494 }
25495 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25496
25497 test_816() {
25498         local ost1_imp=$(get_osc_import_name client ost1)
25499         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25500                          cut -d'.' -f2)
25501
25502         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25503         # ensure ost1 is connected
25504
25505         stat $DIR/$tfile >/dev/null || error "can't stat"
25506         wait_osc_import_state client ost1 FULL
25507         # no locks, no reqs to let the connection idle
25508         cancel_lru_locks osc
25509         lru_resize_disable osc
25510         local before
25511         local now
25512         before=$($LCTL get_param -n \
25513                  ldlm.namespaces.$imp_name.lru_size)
25514
25515         wait_osc_import_state client ost1 IDLE
25516         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25517         now=$($LCTL get_param -n \
25518               ldlm.namespaces.$imp_name.lru_size)
25519         [ $before == $now ] || error "lru_size changed $before != $now"
25520 }
25521 run_test 816 "do not reset lru_resize on idle reconnect"
25522
25523 cleanup_817() {
25524         umount $tmpdir
25525         exportfs -u localhost:$DIR/nfsexp
25526         rm -rf $DIR/nfsexp
25527 }
25528
25529 test_817() {
25530         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25531
25532         mkdir -p $DIR/nfsexp
25533         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25534                 error "failed to export nfs"
25535
25536         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25537         stack_trap cleanup_817 EXIT
25538
25539         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25540                 error "failed to mount nfs to $tmpdir"
25541
25542         cp /bin/true $tmpdir
25543         $DIR/nfsexp/true || error "failed to execute 'true' command"
25544 }
25545 run_test 817 "nfsd won't cache write lock for exec file"
25546
25547 test_818() {
25548         mkdir $DIR/$tdir
25549         $LFS setstripe -c1 -i0 $DIR/$tfile
25550         $LFS setstripe -c1 -i1 $DIR/$tfile
25551         stop $SINGLEMDS
25552         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25553         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25554         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25555                 error "start $SINGLEMDS failed"
25556         rm -rf $DIR/$tdir
25557 }
25558 run_test 818 "unlink with failed llog"
25559
25560 test_819a() {
25561         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25562         cancel_lru_locks osc
25563         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25564         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25565         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25566         rm -f $TDIR/$tfile
25567 }
25568 run_test 819a "too big niobuf in read"
25569
25570 test_819b() {
25571         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25572         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25573         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25574         cancel_lru_locks osc
25575         sleep 1
25576         rm -f $TDIR/$tfile
25577 }
25578 run_test 819b "too big niobuf in write"
25579
25580
25581 function test_820_start_ost() {
25582         sleep 5
25583
25584         for num in $(seq $OSTCOUNT); do
25585                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25586         done
25587 }
25588
25589 test_820() {
25590         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25591
25592         mkdir $DIR/$tdir
25593         umount_client $MOUNT || error "umount failed"
25594         for num in $(seq $OSTCOUNT); do
25595                 stop ost$num
25596         done
25597
25598         # mount client with no active OSTs
25599         # so that the client can't initialize max LOV EA size
25600         # from OSC notifications
25601         mount_client $MOUNT || error "mount failed"
25602         # delay OST starting to keep this 0 max EA size for a while
25603         test_820_start_ost &
25604
25605         # create a directory on MDS2
25606         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25607                 error "Failed to create directory"
25608         # open intent should update default EA size
25609         # see mdc_update_max_ea_from_body()
25610         # notice this is the very first RPC to MDS2
25611         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25612         ret=$?
25613         echo $out
25614         # With SSK, this situation can lead to -EPERM being returned.
25615         # In that case, simply retry.
25616         if [ $ret -ne 0 ] && $SHARED_KEY; then
25617                 if echo "$out" | grep -q "not permitted"; then
25618                         cp /etc/services $DIR/$tdir/mds2
25619                         ret=$?
25620                 fi
25621         fi
25622         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25623 }
25624 run_test 820 "update max EA from open intent"
25625
25626 test_822() {
25627         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25628
25629         save_lustre_params mds1 \
25630                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25631         do_facet $SINGLEMDS "$LCTL set_param -n \
25632                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25633         do_facet $SINGLEMDS "$LCTL set_param -n \
25634                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25635
25636         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25637         local maxage=$(do_facet mds1 $LCTL get_param -n \
25638                        osp.$FSNAME-OST0000*MDT0000.maxage)
25639         sleep $((maxage + 1))
25640
25641         #define OBD_FAIL_NET_ERROR_RPC          0x532
25642         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25643
25644         stack_trap "restore_lustre_params < $p; rm $p"
25645
25646         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25647                       osp.$FSNAME-OST0000*MDT0000.create_count")
25648         for i in $(seq 1 $count); do
25649                 touch $DIR/$tfile.${i} || error "touch failed"
25650         done
25651 }
25652 run_test 822 "test precreate failure"
25653
25654 #
25655 # tests that do cleanup/setup should be run at the end
25656 #
25657
25658 test_900() {
25659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25660         local ls
25661
25662         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25663         $LCTL set_param fail_loc=0x903
25664
25665         cancel_lru_locks MGC
25666
25667         FAIL_ON_ERROR=true cleanup
25668         FAIL_ON_ERROR=true setup
25669 }
25670 run_test 900 "umount should not race with any mgc requeue thread"
25671
25672 # LUS-6253/LU-11185
25673 test_901() {
25674         local oldc
25675         local newc
25676         local olds
25677         local news
25678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25679
25680         # some get_param have a bug to handle dot in param name
25681         cancel_lru_locks MGC
25682         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25683         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25684         umount_client $MOUNT || error "umount failed"
25685         mount_client $MOUNT || error "mount failed"
25686         cancel_lru_locks MGC
25687         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25688         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25689
25690         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25691         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25692
25693         return 0
25694 }
25695 run_test 901 "don't leak a mgc lock on client umount"
25696
25697 # LU-13377
25698 test_902() {
25699         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25700                 skip "client does not have LU-13377 fix"
25701         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25702         $LCTL set_param fail_loc=0x1415
25703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25704         cancel_lru_locks osc
25705         rm -f $DIR/$tfile
25706 }
25707 run_test 902 "test short write doesn't hang lustre"
25708
25709 complete $SECONDS
25710 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25711 check_and_cleanup_lustre
25712 if [ "$I_MOUNTED" != "yes" ]; then
25713         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25714 fi
25715 exit_status